Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hmac secret #229

Merged
merged 5 commits into from
Jul 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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