* 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! */
| 376 | * XXX combine the two functions at some point! |
| 377 | */ |
| 378 | int |
| 379 | AES_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. |
no test coverage detected