Skip to content

Commit

Permalink
Validate challenge (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
qpernil authored Oct 3, 2022
1 parent d267950 commit e9889c6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
19 changes: 19 additions & 0 deletions lib/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ cipher_rc cipher_decrypt(cipher_key key, const unsigned char* in, uint32_t inlen
return CIPHER_OK;
}

uint32_t cipher_blocksize(cipher_key key) {
if (key == NULL) {
return 0;
}
DWORD size = 0;
ULONG len = 0;
if(!BCRYPT_SUCCESS(BCryptGetProperty(key->hKey, BCRYPT_BLOCK_LENGTH, &size, sizeof(size), &len, 0))) {
return 0;
}
return size;
}

#else

static int encrypt_ex(const uint8_t *in, uint8_t *out, int len,
Expand Down Expand Up @@ -242,6 +254,13 @@ cipher_rc cipher_decrypt(cipher_key key, const unsigned char* in, uint32_t inlen
return rc;
}

uint32_t cipher_blocksize(cipher_key key) {
if(key) {
return EVP_CIPHER_block_size(key->cipher);
}
return 0;
}

#endif

bool yk_des_is_weak_key(const unsigned char *key, const size_t cb_key) {
Expand Down
1 change: 1 addition & 0 deletions lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ cipher_rc cipher_import_key(unsigned char algo, const unsigned char *keyraw, uin
cipher_rc cipher_destroy_key(cipher_key key);
cipher_rc cipher_encrypt(cipher_key key, const unsigned char *in, uint32_t inlen, unsigned char *out, uint32_t *outlen);
cipher_rc cipher_decrypt(cipher_key key, const unsigned char *in, uint32_t inlen, unsigned char *out, uint32_t *outlen);
uint32_t cipher_blocksize(cipher_key key);

pkcs5_rc pkcs5_pbkdf2_sha1(const uint8_t* password, const size_t cb_password, const uint8_t* salt, const size_t cb_salt, uint64_t iterations, const uint8_t* key, const size_t cb_key);
bool yk_des_is_weak_key(const unsigned char *key, const size_t cb_key);
Expand Down
19 changes: 11 additions & 8 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,11 @@ static ykpiv_rc _ykpiv_authenticate2(ykpiv_state *state, unsigned const char *ke

uint8_t *challenge = data + 4;
uint32_t challenge_len = recv_len - 4;
if(challenge_len != cipher_blocksize(mgm_key)) { // Only management key block size allowed
DBG("%s: management key block size is %zu but received %u bytes challenge", ykpiv_strerror(YKPIV_PARSE_ERROR), cipher_blocksize(mgm_key), challenge_len);
res = YKPIV_PARSE_ERROR;
goto Cleanup;
}

/* send a response to the cards challenge and a challenge of our own. */
{
Expand All @@ -1007,26 +1012,23 @@ static ykpiv_rc _ykpiv_authenticate2(ykpiv_state *state, unsigned const char *ke
*dataptr++ = challenge_len;
challenge = dataptr;
if (PRNG_GENERAL_ERROR == _ykpiv_prng_generate(challenge, challenge_len)) {
DBG("Failed getting randomness for authentication.");
DBG("%s: Failed getting randomness for authentication.", ykpiv_strerror(YKPIV_RANDOMNESS_ERROR));
res = YKPIV_RANDOMNESS_ERROR;
goto Cleanup;
}
dataptr += challenge_len;
apdu.st.lc = (unsigned char)(dataptr - apdu.st.data);
recv_len = sizeof(data);
if ((res = _ykpiv_send_apdu(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK)
{
if ((res = _ykpiv_send_apdu(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
goto Cleanup;
}
else if (sw != SW_SUCCESS) {
res = YKPIV_AUTHENTICATION_ERROR;
goto Cleanup;
}
}

/* compare the response from the card with our challenge */
{
uint32_t out_len = challenge_len;
/* compare the response from the card with our challenge */
out_len = challenge_len;
drc = cipher_encrypt(mgm_key, challenge, challenge_len, challenge, &out_len);

if (drc != CIPHER_OK) {
Expand Down Expand Up @@ -2126,6 +2128,7 @@ ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, unsign

if (NULL == state) return YKPIV_GENERIC_ERROR;
if (NULL == response) return YKPIV_GENERIC_ERROR;
if (16 < response_len) return YKPIV_GENERIC_ERROR;

if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return res;
/* note: do not select the applet here, as it resets the challenge state */
Expand All @@ -2141,7 +2144,7 @@ ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, unsign
}
}

/* send the response to the card and a challenge of our own. */
/* send the response to the card. */
APDU apdu = {0};
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
apdu.st.p1 = metadata.algorithm;
Expand Down

0 comments on commit e9889c6

Please sign in to comment.