Skip to content

Commit 580c26f

Browse files
committed
Fix PIN P-2, F-1, F-5.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
1 parent a759b76 commit 580c26f

1 file changed

Lines changed: 33 additions & 13 deletions

File tree

src/fido/cbor_client_pin.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,9 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
379379
if (file_has_data(ef_pin)) {
380380
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
381381
}
382-
if ((pinUvAuthProtocol == 1 && newPinEnc.len != 64) ||
383-
(pinUvAuthProtocol == 2 && newPinEnc.len != 64 + IV_SIZE)) {
382+
if ((pinUvAuthProtocol == 1 && (newPinEnc.len < 64 || (newPinEnc.len % 16) != 0)) ||
383+
(pinUvAuthProtocol == 2 &&
384+
(newPinEnc.len < 64 + IV_SIZE || ((newPinEnc.len - IV_SIZE) % 16) != 0))) {
384385
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
385386
}
386387
if (mbedtls_mpi_read_binary(&hkey.ctx.mbed_ecdh.Qp.X, kax.data, kax.len) != 0) {
@@ -399,16 +400,20 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
399400
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
400401
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
401402
}
402-
uint8_t paddedNewPin[64];
403+
uint16_t new_pin_plain_len = pinUvAuthProtocol == 1 ? (uint16_t)newPinEnc.len : (uint16_t)(newPinEnc.len - IV_SIZE);
404+
uint8_t paddedNewPin[256 + IV_SIZE] = { 0 };
405+
if (new_pin_plain_len > sizeof(paddedNewPin)) {
406+
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
407+
}
403408
ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin);
404409
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
405410
if (ret != 0) {
406411
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
407412
}
408-
if (paddedNewPin[63] != 0) {
413+
if (new_pin_plain_len > 64 || paddedNewPin[63] != 0) {
409414
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
410415
}
411-
uint8_t pin_len = 0;
416+
uint16_t pin_len = 0;
412417
while (paddedNewPin[pin_len] != 0 && pin_len < sizeof(paddedNewPin)) {
413418
pin_len++;
414419
}
@@ -456,9 +461,13 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
456461
if (*file_get_data(ef_pin) == 0) {
457462
CBOR_ERROR(CTAP2_ERR_PIN_BLOCKED);
458463
}
459-
if ((pinUvAuthProtocol == 1 && (newPinEnc.len != 64 || pinHashEnc.len != 16)) ||
464+
if ((pinUvAuthProtocol == 1 && ((newPinEnc.len < 64 || (newPinEnc.len % 16) != 0) || pinHashEnc.len != 16)) ||
460465
(pinUvAuthProtocol == 2 &&
461-
(newPinEnc.len != 64 + IV_SIZE || pinHashEnc.len != 16 + IV_SIZE))) {
466+
((newPinEnc.len < 64 + IV_SIZE || ((newPinEnc.len - IV_SIZE) % 16) != 0) || pinHashEnc.len != 16 + IV_SIZE))) {
467+
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
468+
}
469+
if ((pinUvAuthProtocol == 1 && newPinEnc.len > 256) ||
470+
(pinUvAuthProtocol == 2 && newPinEnc.len > 256 + IV_SIZE)) {
462471
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
463472
}
464473
if (mbedtls_mpi_read_binary(&hkey.ctx.mbed_ecdh.Qp.X, kax.data, kax.len) != 0) {
@@ -476,7 +485,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
476485
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
477486
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
478487
}
479-
uint8_t tmp[80 + 32];
488+
uint8_t tmp[256 + IV_SIZE + 32];
480489
memcpy(tmp, newPinEnc.data, newPinEnc.len);
481490
memcpy(tmp + newPinEnc.len, pinHashEnc.data, pinHashEnc.len);
482491
if (verify((uint8_t)pinUvAuthProtocol, sharedSecret, tmp, (uint16_t)(newPinEnc.len + pinHashEnc.len), pinUvAuthParam.data) != 0) {
@@ -492,7 +501,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
492501
CBOR_ERROR(CTAP2_ERR_PROCESSING);
493502
}
494503
uint8_t retries = pin_data[0];
495-
uint8_t paddedNewPin[64];
504+
uint8_t paddedNewPin[256 + IV_SIZE] = { 0 };
496505
ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, pinHashEnc.data, (uint16_t)pinHashEnc.len, paddedNewPin);
497506
if (ret != 0) {
498507
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
@@ -544,15 +553,19 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
544553
}
545554

546555
new_pin_mismatches = 0;
556+
uint16_t new_pin_plain_len = pinUvAuthProtocol == 1 ? (uint16_t)newPinEnc.len : (uint16_t)(newPinEnc.len - IV_SIZE);
557+
if (new_pin_plain_len > sizeof(paddedNewPin)) {
558+
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
559+
}
547560
ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin);
548561
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
549562
if (ret != 0) {
550563
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
551564
}
552-
if (paddedNewPin[63] != 0) {
553-
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
565+
if (new_pin_plain_len > 64 || paddedNewPin[63] != 0) {
566+
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
554567
}
555-
uint8_t pin_len = 0;
568+
uint16_t pin_len = 0;
556569
while (paddedNewPin[pin_len] != 0 && pin_len < sizeof(paddedNewPin)) {
557570
pin_len++;
558571
}
@@ -715,7 +728,14 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
715728
flash_commit();
716729
file_t *ef_minpin = file_search_by_fid(EF_MINPINLEN, NULL, SPECIFY_EF);
717730
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) {
718-
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
731+
if (subcommand == 0x09 &&
732+
permissions == CTAP_PERMISSION_ACFG &&
733+
rpId.present == false) {
734+
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
735+
}
736+
else {
737+
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
738+
}
719739
}
720740
uint8_t pinUvAuthToken_enc[32 + IV_SIZE], *pdata = NULL;
721741
if (permissions & CTAP_PERMISSION_PCMR) {

0 commit comments

Comments
 (0)