@@ -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