13
13
// limitations under the License.
14
14
15
15
#include "cipher.h"
16
- #include <ctaes.h>
17
-
18
- #include <stdlib.h>
19
- #include <string.h>
20
16
21
17
#include <random.h>
22
- #include <util.h>
23
- #include <wally_crypto.h>
18
+ #include <rust/rust.h>
24
19
25
20
#ifdef TESTING
26
21
#include <mock_cipher.h>
27
22
#endif
28
23
29
- #define N_BLOCK (16U)
30
- // Used to sanity-check input to avoid large stack allocations
31
- #define CIPHER_MAX_ALLOC (200U)
32
-
33
- static bool _derive_hmac_keys (
34
- const uint8_t * secret ,
35
- uint8_t * encryption_key_out ,
36
- uint8_t * authentication_key_out )
37
- {
38
- uint8_t hash [64 ];
39
- UTIL_CLEANUP_64 (hash );
40
- if (wally_sha512 (secret , 32 , hash , sizeof (hash )) != WALLY_OK ) {
41
- return false;
42
- }
43
- memcpy (encryption_key_out , hash , 32 );
44
- memcpy (authentication_key_out , hash + 32 , 32 );
45
- return true;
46
- }
47
-
48
- // out_len must be at least in_len + N_BLOCK + N_BLOCK
49
- // necessary in_len/out_len range checks are done in cipher_aes_hmac_encrypt().
50
- static bool _aes_encrypt (
51
- const uint8_t * in ,
24
+ bool cipher_aes_hmac_encrypt (
25
+ const unsigned char * in ,
52
26
size_t in_len ,
53
27
uint8_t * out ,
54
28
size_t * out_len ,
55
- const uint8_t * key )
29
+ const uint8_t * secret )
56
30
{
57
- if (in_len > CIPHER_MAX_ALLOC ) {
58
- return false;
59
- }
60
- size_t padlen = N_BLOCK - in_len % N_BLOCK ;
61
- size_t inpadlen = in_len + padlen ;
62
- uint8_t inpad [inpadlen ];
63
- * out_len = inpadlen + N_BLOCK ;
64
-
65
- // PKCS7 padding
66
- memcpy (inpad , in , in_len );
67
- for (size_t i = 0 ; i < padlen ; i ++ ) {
68
- inpad [in_len + i ] = padlen ;
69
- }
70
-
71
31
uint8_t iv [32 ] = {0 }; // only 16 bytes needed for IV.
72
32
#ifdef TESTING
73
33
cipher_mock_iv (iv );
74
34
#else
75
35
random_32_bytes (iv );
76
36
#endif
77
- memcpy (out , iv , N_BLOCK );
78
-
79
- AES256_CBC_ctx ctx = {0 };
80
- AES256_CBC_init (& ctx , key , iv );
81
- AES256_CBC_encrypt (& ctx , inpadlen / N_BLOCK , out + N_BLOCK , inpad );
82
- * out_len = inpadlen + N_BLOCK ;
83
-
84
- util_zero (inpad , inpadlen );
85
- util_zero (& ctx , sizeof (ctx ));
86
- return true;
87
- }
88
-
89
- bool cipher_aes_hmac_encrypt (
90
- const unsigned char * in ,
91
- size_t in_len ,
92
- uint8_t * out ,
93
- size_t * out_len ,
94
- const uint8_t * secret )
95
- {
96
- // in_len + iv + pad + hmac
97
- if (* out_len != in_len + N_BLOCK + N_BLOCK + 32 ) {
98
- return false;
99
- }
100
- uint8_t encryption_key [32 ];
101
- UTIL_CLEANUP_32 (encryption_key );
102
- uint8_t authentication_key [32 ];
103
- UTIL_CLEANUP_32 (authentication_key );
104
- if (!_derive_hmac_keys (secret , encryption_key , authentication_key )) {
105
- return false;
106
- }
107
-
108
- size_t encrypt_len = in_len + 32 ;
109
- if (!_aes_encrypt (in , in_len , out , & encrypt_len , encryption_key )) {
110
- return false;
111
- }
112
-
113
- * out_len = encrypt_len + 32 ;
114
-
115
- return wally_hmac_sha256 (
116
- authentication_key ,
117
- sizeof (authentication_key ),
118
- out ,
119
- encrypt_len ,
120
- out + encrypt_len ,
121
- 32 ) == WALLY_OK ;
122
- }
123
-
124
- // necessary in_len/out_len range checks are done in cipher_aes_hmac_decrypt().
125
- static bool _aes_decrypt (
126
- const uint8_t * in ,
127
- size_t in_len ,
128
- uint8_t * out ,
129
- size_t * out_len ,
130
- const uint8_t * key )
131
- {
132
- if (in_len > CIPHER_MAX_ALLOC ) {
133
- return false;
134
- }
135
- uint8_t dec_pad [in_len - N_BLOCK ];
136
- const uint8_t * iv = in ; // first 16 bytes
137
-
138
- AES256_CBC_ctx ctx = {0 };
139
- AES256_CBC_init (& ctx , key , iv );
140
- AES256_CBC_decrypt (& ctx , in_len / N_BLOCK - 1 , dec_pad , in + N_BLOCK );
141
-
142
- // Strip PKCS7 padding
143
- uint8_t padlen = dec_pad [in_len - N_BLOCK - 1 ];
144
- if (padlen > N_BLOCK ) {
145
- goto error ;
146
- }
147
- if (in_len < N_BLOCK + padlen ) {
148
- goto error ;
149
- }
150
- for (size_t i = 0 ; i < padlen ; i ++ ) {
151
- if (dec_pad [in_len - N_BLOCK - 1 - i ] != padlen ) {
152
- goto error ;
153
- }
154
- }
155
- memcpy (out , dec_pad , in_len - N_BLOCK - padlen );
156
- * out_len = in_len - N_BLOCK - padlen ;
157
- util_zero (dec_pad , sizeof (dec_pad ));
158
- util_zero (& ctx , sizeof (ctx ));
37
+ rust_cipher_encrypt (
38
+ rust_util_bytes (iv , 16 ),
39
+ rust_util_bytes (secret , 32 ),
40
+ rust_util_bytes (in , in_len ),
41
+ rust_util_bytes_mut (out , * out_len ),
42
+ out_len );
159
43
return true;
160
- error :
161
- util_zero (dec_pad , sizeof (dec_pad ));
162
- util_zero (& ctx , sizeof (ctx ));
163
- return false;
164
44
}
165
45
166
46
bool cipher_aes_hmac_decrypt (
@@ -170,38 +50,9 @@ bool cipher_aes_hmac_decrypt(
170
50
size_t * out_len ,
171
51
const uint8_t * key )
172
52
{
173
- // iv + pad + hmac
174
- if (in_len < N_BLOCK + N_BLOCK + 32 ) {
175
- return false;
176
- }
177
- // have space for at least in_len - iv - hmac
178
- if (* out_len != in_len - N_BLOCK - 32 ) {
179
- return false;
180
- }
181
-
182
- uint8_t encryption_key [32 ];
183
- UTIL_CLEANUP_32 (encryption_key );
184
- uint8_t authentication_key [32 ];
185
- UTIL_CLEANUP_32 (authentication_key );
186
-
187
- if (!_derive_hmac_keys (key , encryption_key , authentication_key )) {
188
- return false;
189
- }
190
-
191
- uint8_t hmac [32 ];
192
- UTIL_CLEANUP_32 (hmac );
193
- if (wally_hmac_sha256 (
194
- authentication_key ,
195
- sizeof (authentication_key ),
196
- in ,
197
- in_len - sizeof (hmac ),
198
- hmac ,
199
- sizeof (hmac )) != WALLY_OK ) {
200
- return false;
201
- }
202
-
203
- if (!MEMEQ (hmac , in + in_len - sizeof (hmac ), sizeof (hmac ))) {
204
- return false;
205
- }
206
- return _aes_decrypt (in , in_len - sizeof (hmac ), out , out_len , encryption_key );
53
+ return rust_cipher_decrypt (
54
+ rust_util_bytes (key , 32 ),
55
+ rust_util_bytes (in , in_len ),
56
+ rust_util_bytes_mut (out , * out_len ),
57
+ out_len );
207
58
}
0 commit comments