| 105 | } |
| 106 | |
| 107 | bool ChaCha20Poly1305AEAD::GetLength(uint32_t* len24_out, uint64_t seqnr_aad, int aad_pos, const uint8_t* ciphertext) |
| 108 | { |
| 109 | // enforce valid aad position to avoid accessing outside of the 64byte keystream cache |
| 110 | // (there is space for 21 times 3 bytes) |
| 111 | assert(aad_pos >= 0 && aad_pos < CHACHA20_ROUND_OUTPUT - CHACHA20_POLY1305_AEAD_AAD_LEN); |
| 112 | if (m_cached_aad_seqnr != seqnr_aad) { |
| 113 | // we need to calculate the 64 keystream bytes since we reached a new aad sequence number |
| 114 | m_cached_aad_seqnr = seqnr_aad; |
| 115 | m_chacha_header.SetIV(seqnr_aad); // use LE for the nonce |
| 116 | m_chacha_header.Seek(0); // block counter 0 |
| 117 | m_chacha_header.Keystream(m_aad_keystream_buffer, CHACHA20_ROUND_OUTPUT); // write keystream to the cache |
| 118 | } |
| 119 | |
| 120 | // decrypt the ciphertext length by XORing the right position of the 64byte keystream cache with the ciphertext |
| 121 | *len24_out = (ciphertext[0] ^ m_aad_keystream_buffer[aad_pos + 0]) | |
| 122 | (ciphertext[1] ^ m_aad_keystream_buffer[aad_pos + 1]) << 8 | |
| 123 | (ciphertext[2] ^ m_aad_keystream_buffer[aad_pos + 2]) << 16; |
| 124 | |
| 125 | return true; |
| 126 | } |