Skip to content

Commit 2af747d

Browse files
authored
Merge pull request #229 from solokeys/fix-hmac-secret
Fix hmac secret
2 parents 9ead11d + f17faca commit 2af747d

File tree

6 files changed

+71
-6
lines changed

6 files changed

+71
-6
lines changed

fido2/crypto.h

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, ui
3838
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey);
3939
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret);
4040

41+
#define CRYPTO_TRANSPORT_KEY2 ((uint8_t*)2)
4142
#define CRYPTO_TRANSPORT_KEY ((uint8_t*)1)
4243
#define CRYPTO_MASTER_KEY ((uint8_t*)0)
4344

fido2/ctap.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,9 @@ static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf
355355
}
356356

357357
// Generate credRandom
358-
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY, 0, credRandom);
358+
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
359359
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
360-
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY, 0, credRandom);
360+
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
361361

362362
// Decrypt saltEnc
363363
crypto_aes256_init(shared_secret, NULL);
@@ -605,7 +605,6 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa
605605
crypto_sha256_final(hashbuf);
606606

607607
crypto_ecc256_sign(hashbuf, 32, sigbuf);
608-
609608
return ctap_encode_der_sig(sigbuf,sigder);
610609
}
611610

@@ -1056,7 +1055,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
10561055
else
10571056
#endif
10581057
{
1059-
sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
1058+
sigder_sz = ctap_calculate_signature(auth_data_buf, auth_data_buf_sz, clientDataHash, auth_data_buf, sigbuf, sigder);
10601059
}
10611060

10621061
{

targets/stm32l432/src/crypto.c

+5
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
157157
key = master_secret;
158158
klen = sizeof(master_secret)/2;
159159
}
160+
else if (key == CRYPTO_TRANSPORT_KEY2)
161+
{
162+
key = transport_secret;
163+
klen = 32;
164+
}
160165

161166

162167
if(klen > 64)

tools/testing/tests/fido2.py

+39-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def test_extensions(self,):
211211
assert "hmac-secret" in reg.auth_data.extensions
212212
assert reg.auth_data.extensions["hmac-secret"] == True
213213

214-
reg = self.testMC(
214+
self.testMC(
215215
"Send MC with fake extension set to true, expect SUCCESS",
216216
cdh,
217217
rp,
@@ -278,6 +278,10 @@ def get_salt_params(salts):
278278
assert shannon_entropy(ext["hmac-secret"]) > 5.4
279279
assert shannon_entropy(key) > 5.4
280280

281+
with Test("Check that the assertion is valid"):
282+
credential_data = AttestedCredentialData(reg.auth_data.credential_data)
283+
auth.verify(cdh, credential_data.public_key)
284+
281285
salt_enc, salt_auth = get_salt_params((salt3,))
282286

283287
auth = self.testGA(
@@ -743,6 +747,40 @@ def test_get_assertion(self,):
743747
expectedError=CtapError.ERR.SUCCESS,
744748
)
745749

750+
with Test("Check assertion is correct"):
751+
credential_data = AttestedCredentialData(prev_reg.auth_data.credential_data)
752+
prev_auth.verify(cdh, credential_data.public_key)
753+
assert (
754+
prev_auth.credential["id"]
755+
== prev_reg.auth_data.credential_data.credential_id
756+
)
757+
758+
self.reboot()
759+
760+
prev_auth = self.testGA(
761+
"Send GA request after reboot, expect success",
762+
rp["id"],
763+
cdh,
764+
allow_list,
765+
expectedError=CtapError.ERR.SUCCESS,
766+
)
767+
768+
with Test("Check assertion is correct"):
769+
credential_data = AttestedCredentialData(prev_reg.auth_data.credential_data)
770+
prev_auth.verify(cdh, credential_data.public_key)
771+
assert (
772+
prev_auth.credential["id"]
773+
== prev_reg.auth_data.credential_data.credential_id
774+
)
775+
776+
prev_auth = self.testGA(
777+
"Send GA request, expect success",
778+
rp["id"],
779+
cdh,
780+
allow_list,
781+
expectedError=CtapError.ERR.SUCCESS,
782+
)
783+
746784
with Test("Test auth_data is 37 bytes"):
747785
assert len(prev_auth.auth_data) == 37
748786

tools/testing/tests/tester.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from fido2.hid import CtapHidDevice
44
from fido2.client import Fido2Client
5+
from fido2.attestation import Attestation
56
from fido2.ctap1 import CTAP1
67
from fido2.utils import Timeout
78

@@ -201,7 +202,18 @@ def testReset(self,):
201202
self.ctap.reset()
202203

203204
def testMC(self, test, *args, **kwargs):
204-
return self.testFunc(self.ctap.make_credential, test, *args, **kwargs)
205+
attestation_object = self.testFunc(
206+
self.ctap.make_credential, test, *args, **kwargs
207+
)
208+
if attestation_object:
209+
verifier = Attestation.for_type(attestation_object.fmt)
210+
client_data = args[0]
211+
verifier().verify(
212+
attestation_object.att_statement,
213+
attestation_object.auth_data,
214+
client_data,
215+
)
216+
return attestation_object
205217

206218
def testGA(self, test, *args, **kwargs):
207219
return self.testFunc(self.ctap.get_assertion, test, *args, **kwargs)

tools/testing/tests/u2f.py

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ def test_u2f(self,):
7878
auth = self.authenticate(chal, appid, regs[i].key_handle)
7979
auth.verify(appid, chal, regs[i].public_key)
8080

81+
self.reboot()
82+
83+
for i in range(0, self.user_count):
84+
with Test(
85+
"Post reboot, Checking previous registration %d/%d"
86+
% (i + 1, self.user_count)
87+
):
88+
auth = self.authenticate(chal, appid, regs[i].key_handle)
89+
auth.verify(appid, chal, regs[i].public_key)
90+
8191
print("Check that all previous credentials are registered...")
8292
for i in range(0, self.user_count):
8393
with Test("Check that previous credential %d is registered" % i):

0 commit comments

Comments
 (0)