Branch data Line data Source code
1 : : // Copyright (c) 2016-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 : :
5 : : #include <crypto/aes.h>
6 : :
7 : : #include <string.h>
8 : :
9 : : extern "C" {
10 : : #include <crypto/ctaes/ctaes.c>
11 : : }
12 : :
13 : 96 : AES256Encrypt::AES256Encrypt(const unsigned char key[32])
14 : : {
15 : 96 : AES256_init(&ctx, key);
16 : 96 : }
17 : :
18 : 96 : AES256Encrypt::~AES256Encrypt()
19 : : {
20 : 96 : memset(&ctx, 0, sizeof(ctx));
21 : 96 : }
22 : :
23 : 27141 : void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
24 : : {
25 : 27141 : AES256_encrypt(&ctx, 1, ciphertext, plaintext);
26 : 27141 : }
27 : :
28 : 96 : AES256Decrypt::AES256Decrypt(const unsigned char key[32])
29 : : {
30 : 96 : AES256_init(&ctx, key);
31 : 96 : }
32 : :
33 : 96 : AES256Decrypt::~AES256Decrypt()
34 : : {
35 : 96 : memset(&ctx, 0, sizeof(ctx));
36 : 96 : }
37 : :
38 : 27141 : void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
39 : : {
40 : 27141 : AES256_decrypt(&ctx, 1, plaintext, ciphertext);
41 : 27141 : }
42 : :
43 : :
44 : : template <typename T>
45 : 15333 : static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
46 : : {
47 : 15333 : int written = 0;
48 : 15333 : int padsize = size % AES_BLOCKSIZE;
49 : : unsigned char mixed[AES_BLOCKSIZE];
50 : :
51 [ + + + - : 15333 : if (!data || !size || !out)
- + ]
52 : 3700 : return 0;
53 : :
54 [ + + + + ]: 11633 : if (!pad && padsize != 0)
55 : 235 : return 0;
56 : :
57 : 11398 : memcpy(mixed, iv, AES_BLOCKSIZE);
58 : :
59 : : // Write all but the last block
60 [ + + ]: 26685 : while (written + AES_BLOCKSIZE <= size) {
61 [ + + ]: 259879 : for (int i = 0; i != AES_BLOCKSIZE; i++)
62 : 244592 : mixed[i] ^= *data++;
63 : 15287 : enc.Encrypt(out + written, mixed);
64 : 15287 : memcpy(mixed, out + written, AES_BLOCKSIZE);
65 : 15287 : written += AES_BLOCKSIZE;
66 : : }
67 [ + + ]: 11398 : if (pad) {
68 : : // For all that remains, pad each byte with the value of the remaining
69 : : // space. If there is none, pad by a full block.
70 [ + + ]: 45844 : for (int i = 0; i != padsize; i++)
71 : 34640 : mixed[i] ^= *data++;
72 [ + + ]: 155828 : for (int i = padsize; i != AES_BLOCKSIZE; i++)
73 : 144624 : mixed[i] ^= AES_BLOCKSIZE - padsize;
74 : 11204 : enc.Encrypt(out + written, mixed);
75 : 11204 : written += AES_BLOCKSIZE;
76 : 11204 : }
77 : 11398 : return written;
78 : 15333 : }
79 : :
80 : : template <typename T>
81 : 15333 : static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
82 : : {
83 : 15333 : int written = 0;
84 : 15333 : bool fail = false;
85 : 15333 : const unsigned char* prev = iv;
86 : :
87 [ + - + + : 15333 : if (!data || !size || !out)
- + ]
88 : 3935 : return 0;
89 : :
90 [ - + ]: 11398 : if (size % AES_BLOCKSIZE != 0)
91 : 0 : return 0;
92 : :
93 : : // Decrypt all data. Padding will be checked in the output.
94 [ + + ]: 37889 : while (written != size) {
95 : 26491 : dec.Decrypt(out, data + written);
96 [ + + ]: 450347 : for (int i = 0; i != AES_BLOCKSIZE; i++)
97 : 423856 : *out++ ^= prev[i];
98 : 26491 : prev = data + written;
99 : 26491 : written += AES_BLOCKSIZE;
100 : : }
101 : :
102 : : // When decrypting padding, attempt to run in constant-time
103 [ + + ]: 11398 : if (pad) {
104 : : // If used, padding size is the value of the last decrypted byte. For
105 : : // it to be valid, It must be between 1 and AES_BLOCKSIZE.
106 : 11204 : unsigned char padsize = *--out;
107 : 11204 : fail = !padsize | (padsize > AES_BLOCKSIZE);
108 : :
109 : : // If not well-formed, treat it as though there's no padding.
110 : 11204 : padsize *= !fail;
111 : :
112 : : // All padding must equal the last byte otherwise it's not well-formed
113 [ + + ]: 190468 : for (int i = AES_BLOCKSIZE; i != 0; i--)
114 : 179264 : fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
115 : :
116 : 11204 : written -= padsize;
117 : 11204 : }
118 : 11398 : return written * !fail;
119 : 15333 : }
120 : :
121 : 77 : AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
122 : 77 : : enc(key), pad(padIn)
123 : : {
124 : 77 : memcpy(iv, ivIn, AES_BLOCKSIZE);
125 : 77 : }
126 : :
127 : 15333 : int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
128 : : {
129 : 15333 : return CBCEncrypt(enc, iv, data, size, pad, out);
130 : : }
131 : :
132 : 77 : AES256CBCEncrypt::~AES256CBCEncrypt()
133 : : {
134 : 77 : memset(iv, 0, sizeof(iv));
135 : 77 : }
136 : :
137 : 77 : AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
138 : 77 : : dec(key), pad(padIn)
139 : : {
140 : 77 : memcpy(iv, ivIn, AES_BLOCKSIZE);
141 : 77 : }
142 : :
143 : :
144 : 15333 : int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
145 : : {
146 : 15333 : return CBCDecrypt(dec, iv, data, size, pad, out);
147 : : }
148 : :
149 : 77 : AES256CBCDecrypt::~AES256CBCDecrypt()
150 : : {
151 : 77 : memset(iv, 0, sizeof(iv));
152 : 77 : }
|