CCM nonce is 7..13 bytes

This commit is contained in:
Karel Miko 2026-07-18 14:31:56 +02:00 committed by Steffen Jaeckel
parent 1027dcfaf6
commit e00b22d939
4 changed files with 60 additions and 8 deletions

View file

@ -1354,7 +1354,7 @@ static void time_ccm(eac_ctx *ctx)
t_start();
t1 = t_read();
z = 16;
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 13, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
@ -1369,7 +1369,7 @@ static void time_ccm(eac_ctx *ctx)
t_start();
t1 = t_read();
z = 16;
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 13, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}

View file

@ -20,8 +20,11 @@ int ccm_add_nonce(ccm_state *ccm,
LTC_ARGCHK(ccm != NULL);
LTC_ARGCHK(nonce != NULL);
/* increase L to match the nonce len */
ccm->noncelen = (noncelen > 13) ? 13 : noncelen;
/* CCM nonce is 7..13 bytes */
if (noncelen < 7 || noncelen > 13) {
return CRYPT_INVALID_ARG;
}
ccm->noncelen = noncelen;
if ((15 - ccm->noncelen) > ccm->L) {
ccm->L = 15 - ccm->noncelen;
}
@ -29,9 +32,9 @@ int ccm_add_nonce(ccm_state *ccm,
return CRYPT_INVALID_ARG;
}
/* decrease noncelen to match L */
/* flags byte + nonce + length field must fit the 16-byte block */
if ((ccm->noncelen + ccm->L) > 15) {
ccm->noncelen = 15 - ccm->L;
return CRYPT_INVALID_ARG;
}
/* form B_0 == flags | Nonce N | l(m) */

View file

@ -78,7 +78,8 @@ int ccm_memory(int cipher,
if (*taglen < 4 || *taglen > 16 || (*taglen % 2) == 1 || headerlen > 0x7fffffffu) {
return CRYPT_INVALID_ARG;
}
if (noncelen < 7) {
/* CCM nonce is 7..13 bytes */
if (noncelen < 7 || noncelen > 13) {
return CRYPT_INVALID_ARG;
}
@ -107,7 +108,6 @@ int ccm_memory(int cipher,
}
/* increase L to match the nonce len */
noncelen = (noncelen > 13) ? 13 : noncelen;
if ((15 - noncelen) > L) {
L = 15 - noncelen;
}
@ -115,6 +115,11 @@ int ccm_memory(int cipher,
return CRYPT_INVALID_ARG;
}
/* flags byte + nonce + length field must fit the 16-byte block */
if ((noncelen + L) > 15) {
return CRYPT_INVALID_ARG;
}
/* allocate mem for the symmetric key */
if (uskey == NULL) {
skey = XMALLOC(sizeof(*skey));

View file

@ -267,6 +267,50 @@ int ccm_test(void)
}
}
/* invalid nonce lengths and nonce/L combinations must be rejected not silently adjusted */
{
unsigned char key[16] = { 0 };
unsigned char nonce[16] = { 0 };
unsigned char pt[16] = { 0 };
unsigned char ct[16];
/* CCM nonce is 7..13 bytes */
taglen = 8;
if (ccm_memory(idx, key, sizeof(key), NULL, nonce, 6, NULL, 0, pt, sizeof(pt), ct, tag, &taglen, CCM_ENCRYPT) != CRYPT_INVALID_ARG) {
return CRYPT_FAIL_TESTVECTOR;
}
taglen = 8;
if (ccm_memory(idx, key, sizeof(key), NULL, nonce, 14, NULL, 0, pt, sizeof(pt), ct, tag, &taglen, CCM_ENCRYPT) != CRYPT_INVALID_ARG) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = ccm_init(&ccm, idx, key, sizeof(key), sizeof(pt), 8, 0)) != CRYPT_OK) {
return err;
}
if (ccm_add_nonce(&ccm, nonce, 6) != CRYPT_INVALID_ARG) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = ccm_init(&ccm, idx, key, sizeof(key), sizeof(pt), 8, 0)) != CRYPT_OK) {
return err;
}
if (ccm_add_nonce(&ccm, nonce, 14) != CRYPT_INVALID_ARG) {
return CRYPT_FAIL_TESTVECTOR;
}
/* ptlen >= 2^16 forces L=3, so a 13-byte nonce no longer fits B_0 (13+3 > 15) */
if ((err = ccm_init(&ccm, idx, key, sizeof(key), 65536, 8, 0)) != CRYPT_OK) {
return err;
}
if (ccm_add_nonce(&ccm, nonce, 13) != CRYPT_INVALID_ARG) {
return CRYPT_FAIL_TESTVECTOR;
}
/* 12-byte nonce still fits (12+3 == 15) */
if ((err = ccm_init(&ccm, idx, key, sizeof(key), 65536, 8, 0)) != CRYPT_OK) {
return err;
}
if ((err = ccm_add_nonce(&ccm, nonce, 12)) != CRYPT_OK) {
return err;
}
}
return CRYPT_OK;
#endif
}