Skip to content

Commit

Permalink
Merge pull request #229 from solokeys/fix-hmac-secret
Browse files Browse the repository at this point in the history
Fix hmac secret
  • Loading branch information
conorpp authored Jul 27, 2019
2 parents 9ead11d + f17faca commit 2af747d
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
1 change: 1 addition & 0 deletions fido2/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, ui
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey);
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret);

#define CRYPTO_TRANSPORT_KEY2 ((uint8_t*)2)
#define CRYPTO_TRANSPORT_KEY ((uint8_t*)1)
#define CRYPTO_MASTER_KEY ((uint8_t*)0)

Expand Down
7 changes: 3 additions & 4 deletions fido2/ctap.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf
}

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

// Decrypt saltEnc
crypto_aes256_init(shared_secret, NULL);
Expand Down Expand Up @@ -605,7 +605,6 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa
crypto_sha256_final(hashbuf);

crypto_ecc256_sign(hashbuf, 32, sigbuf);

return ctap_encode_der_sig(sigbuf,sigder);
}

Expand Down Expand Up @@ -1056,7 +1055,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
else
#endif
{
sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
sigder_sz = ctap_calculate_signature(auth_data_buf, auth_data_buf_sz, clientDataHash, auth_data_buf, sigbuf, sigder);
}

{
Expand Down
5 changes: 5 additions & 0 deletions targets/stm32l432/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
key = master_secret;
klen = sizeof(master_secret)/2;
}
else if (key == CRYPTO_TRANSPORT_KEY2)
{
key = transport_secret;
klen = 32;
}


if(klen > 64)
Expand Down
40 changes: 39 additions & 1 deletion tools/testing/tests/fido2.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def test_extensions(self,):
assert "hmac-secret" in reg.auth_data.extensions
assert reg.auth_data.extensions["hmac-secret"] == True

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

with Test("Check that the assertion is valid"):
credential_data = AttestedCredentialData(reg.auth_data.credential_data)
auth.verify(cdh, credential_data.public_key)

salt_enc, salt_auth = get_salt_params((salt3,))

auth = self.testGA(
Expand Down Expand Up @@ -743,6 +747,40 @@ def test_get_assertion(self,):
expectedError=CtapError.ERR.SUCCESS,
)

with Test("Check assertion is correct"):
credential_data = AttestedCredentialData(prev_reg.auth_data.credential_data)
prev_auth.verify(cdh, credential_data.public_key)
assert (
prev_auth.credential["id"]
== prev_reg.auth_data.credential_data.credential_id
)

self.reboot()

prev_auth = self.testGA(
"Send GA request after reboot, expect success",
rp["id"],
cdh,
allow_list,
expectedError=CtapError.ERR.SUCCESS,
)

with Test("Check assertion is correct"):
credential_data = AttestedCredentialData(prev_reg.auth_data.credential_data)
prev_auth.verify(cdh, credential_data.public_key)
assert (
prev_auth.credential["id"]
== prev_reg.auth_data.credential_data.credential_id
)

prev_auth = self.testGA(
"Send GA request, expect success",
rp["id"],
cdh,
allow_list,
expectedError=CtapError.ERR.SUCCESS,
)

with Test("Test auth_data is 37 bytes"):
assert len(prev_auth.auth_data) == 37

Expand Down
14 changes: 13 additions & 1 deletion tools/testing/tests/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from fido2.hid import CtapHidDevice
from fido2.client import Fido2Client
from fido2.attestation import Attestation
from fido2.ctap1 import CTAP1
from fido2.utils import Timeout

Expand Down Expand Up @@ -201,7 +202,18 @@ def testReset(self,):
self.ctap.reset()

def testMC(self, test, *args, **kwargs):
return self.testFunc(self.ctap.make_credential, test, *args, **kwargs)
attestation_object = self.testFunc(
self.ctap.make_credential, test, *args, **kwargs
)
if attestation_object:
verifier = Attestation.for_type(attestation_object.fmt)
client_data = args[0]
verifier().verify(
attestation_object.att_statement,
attestation_object.auth_data,
client_data,
)
return attestation_object

def testGA(self, test, *args, **kwargs):
return self.testFunc(self.ctap.get_assertion, test, *args, **kwargs)
Expand Down
10 changes: 10 additions & 0 deletions tools/testing/tests/u2f.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ def test_u2f(self,):
auth = self.authenticate(chal, appid, regs[i].key_handle)
auth.verify(appid, chal, regs[i].public_key)

self.reboot()

for i in range(0, self.user_count):
with Test(
"Post reboot, Checking previous registration %d/%d"
% (i + 1, self.user_count)
):
auth = self.authenticate(chal, appid, regs[i].key_handle)
auth.verify(appid, chal, regs[i].public_key)

print("Check that all previous credentials are registered...")
for i in range(0, self.user_count):
with Test("Check that previous credential %d is registered" % i):
Expand Down

0 comments on commit 2af747d

Please sign in to comment.