Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
chacha_poly_aead.cpp
Go to the documentation of this file.
1// Copyright (c) 2019 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6
7#include <crypto/poly1305.h>
8#include <support/cleanse.h>
9
10#include <cassert>
11#include <cstring>
12
13#include <cstdio>
14#include <limits>
15
16#ifndef HAVE_TIMINGSAFE_BCMP
17
18int timingsafe_bcmp(const uint8_t *b1, const uint8_t *b2, size_t n) {
19 const uint8_t *p1 = b1, *p2 = b2;
20 int ret = 0;
21
22 for (; n > 0; n--) {
23 ret |= *p1++ ^ *p2++;
24 }
25 return (ret != 0);
26}
27
28#endif // TIMINGSAFE_BCMP
29
31 const uint8_t *K_2, size_t K_2_len) {
36
37 // set the cached sequence number to uint64 max which hints for an unset
38 // cache. we can't hit uint64 max since the rekey rule (which resets the
39 // sequence number) is 1GB
40 m_cached_aad_seqnr = std::numeric_limits<uint64_t>::max();
41}
42
45 size_t dest_len /* length of the output buffer for sanity checks */,
46 const uint8_t *src, size_t src_len, bool is_encrypt) {
47 // check buffer boundaries
48 if (
49 // if we encrypt, make sure the source contains at least the expected
50 // AAD and the destination has at least space for the source + MAC
53 // if we decrypt, make sure the source contains at least the expected
54 // AAD+MAC and the destination has at least space for the source - MAC
55 (!is_encrypt &&
58 return false;
59 }
60
62 memset(poly_key, 0, sizeof(poly_key));
64
65 // block counter 0 for the poly1305 key
66 // use lower 32bytes for the poly1305 key
67 // (throws away 32 unused bytes (upper 32) from this ChaCha20 round)
70
71 // if decrypting, verify the tag prior to decryption
72 if (!is_encrypt) {
73 const uint8_t *tag = src + src_len - POLY1305_TAGLEN;
75
76 // constant time compare the calculated MAC with the provided MAC
80 return false;
81 }
83 // MAC has been successfully verified, make sure we don't covert it in
84 // decryption
86 }
87
88 // calculate and cache the next 64byte keystream block if requested sequence
89 // number is not yet the cache
96 }
97 // crypt the AAD (3 bytes message length) with given position in AAD cipher
98 // instance keystream
99 dest[0] = src[0] ^ m_aad_keystream_buffer[aad_pos];
100 dest[1] = src[1] ^ m_aad_keystream_buffer[aad_pos + 1];
101 dest[2] = src[2] ^ m_aad_keystream_buffer[aad_pos + 2];
102
103 // Set the playload ChaCha instance block counter to 1 and crypt the payload
108
109 // If encrypting, calculate and append tag
110 if (is_encrypt) {
111 // the poly1305 tag expands over the AAD (3 bytes length) & encrypted
112 // payload
113 poly1305_auth(dest + src_len, dest, src_len, poly_key);
114 }
115
116 // cleanse no longer required MAC and polykey
118 return true;
119}
120
122 int aad_pos, const uint8_t *ciphertext) {
123 // enforce valid aad position to avoid accessing outside of the 64byte
124 // keystream cache (there is space for 21 times 3 bytes)
125 assert(aad_pos >= 0 &&
128 // we need to calculate the 64 keystream bytes since we reached a new
129 // aad sequence number
131 // use LE for the nonce
133 // block counter 0
135 // write keystream to the cache
138 }
139
140 // decrypt the ciphertext length by XORing the right position of the 64byte
141 // keystream cache with the ciphertext
143 (ciphertext[1] ^ m_aad_keystream_buffer[aad_pos + 1]) << 8 |
144 (ciphertext[2] ^ m_aad_keystream_buffer[aad_pos + 2]) << 16;
145
146 return true;
147}
static constexpr int CHACHA20_POLY1305_AEAD_KEY_LEN
static constexpr int CHACHA20_POLY1305_AEAD_AAD_LEN
static constexpr int CHACHA20_ROUND_OUTPUT
void SetKey(const uint8_t *key, size_t keylen)
set key with flexible keylength; 256bit recommended
Definition chacha20.cpp:32
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition chacha20.cpp:79
void Crypt(const uint8_t *input, uint8_t *output, size_t bytes)
enciphers the message <input> of length <bytes> and write the enciphered representation into <output>...
Definition chacha20.cpp:194
void SetIV(uint64_t iv)
Definition chacha20.cpp:69
void Seek(uint64_t pos)
Definition chacha20.cpp:74
bool Crypt(uint64_t seqnr_payload, uint64_t seqnr_aad, int aad_pos, uint8_t *dest, size_t dest_len, const uint8_t *src, size_t src_len, bool is_encrypt)
Encrypts/decrypts a packet.
bool GetLength(uint32_t *len24_out, uint64_t seqnr_aad, int aad_pos, const uint8_t *ciphertext)
decrypts the 3 bytes AAD data and decodes it into a uint32_t field
uint8_t m_aad_keystream_buffer[CHACHA20_ROUND_OUTPUT]
ChaCha20Poly1305AEAD(const uint8_t *K_1, size_t K_1_len, const uint8_t *K_2, size_t K_2_len)
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition cleanse.cpp:14
int timingsafe_bcmp(const uint8_t *b1, const uint8_t *b2, size_t n)
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN])
Definition poly1305.cpp:15
#define POLY1305_KEYLEN
Definition poly1305.h:11
#define POLY1305_TAGLEN
Definition poly1305.h:12
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
assert(!tx.IsCoinBase())