MCPcopy Create free account
hub / github.com/F-Stack/f-stack / AES_CCM_decrypt

Function AES_CCM_decrypt

freebsd/crypto/aesni/aesni_ccm.c:378–439  ·  view source on GitHub ↗

* The exposed decryption routine. This is practically a * copy of the encryption routine, except that the order * in which the tag is created is changed. * XXX combine the two functions at some point! */

Source from the content-addressed store, hash-verified

376 * XXX combine the two functions at some point!
377 */
378int
379AES_CCM_decrypt(const unsigned char *in, unsigned char *out,
380 const unsigned char *addt, const unsigned char *nonce,
381 const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int nlen,
382 const unsigned char *key, int nr)
383{
384 static const int tag_length = 16; /* 128 bits */
385 int L;
386 __m128i s0, rolling_mac, staging_block;
387 uint8_t *byte_ptr;
388
389 if (nbytes == 0 && abytes == 0)
390 return (1); // No message means no decryption!
391 if (nlen < 0 || nlen > 15)
392 panic("%s: bad nonce length %d", __FUNCTION__, nlen);
393
394 /*
395 * We need to know how many bytes to use to describe
396 * the length of the data. Normally, nlen should be
397 * 12, which leaves us 3 bytes to do that -- 16mbytes of
398 * data to encrypt. But it can be longer or shorter.
399 */
400 L = sizeof(__m128i) - 1 - nlen;
401
402 /*
403 * Now, this shouldn't happen, but let's make sure that
404 * the data length isn't too big.
405 */
406 if (nbytes > ((1 << (8 * L)) - 1))
407 panic("%s: nbytes is %u, but length field is %d bytes",
408 __FUNCTION__, nbytes, L);
409 /*
410 * Clear out the blocks
411 */
412 s0 = _mm_setzero_si128();
413
414 rolling_mac = cbc_mac_start(addt, abytes, nonce, nlen,
415 key, nr, nbytes, tag_length);
416 /* s0 has flags, nonce, and then 0 */
417 byte_ptr = (uint8_t*)&s0;
418 byte_ptr[0] = L-1; /* but the flags byte only has L' */
419 bcopy(nonce, &byte_ptr[1], nlen);
420
421 /*
422 * Now to cycle through the rest of the data.
423 */
424 decrypt_loop(in, NULL, nbytes, s0, nlen, &rolling_mac, key, nr);
425
426 /*
427 * Compare the tag.
428 */
429 staging_block = _mm_xor_si128(AESNI_ENC(s0, key, nr), rolling_mac);
430 if (timingsafe_bcmp(&staging_block, tag, tag_length) != 0) {
431 return (0);
432 }
433
434 /*
435 * Push out the decryption results this time.

Callers 1

aesni_cipher_cryptFunction · 0.85

Calls 4

cbc_mac_startFunction · 0.85
decrypt_loopFunction · 0.85
timingsafe_bcmpFunction · 0.85
panicFunction · 0.50

Tested by

no test coverage detected