1313// limitations under the License.
1414
1515#include "cipher.h"
16- #include <ctaes.h>
17-
18- #include <stdlib.h>
19- #include <string.h>
2016
2117#include <random.h>
22- #include <util.h>
23- #include <wally_crypto.h>
18+ #include <rust/rust.h>
2419
2520#ifdef TESTING
2621#include <mock_cipher.h>
2722#endif
2823
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 ,
5226 size_t in_len ,
5327 uint8_t * out ,
5428 size_t * out_len ,
55- const uint8_t * key )
29+ const uint8_t * secret )
5630{
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-
7131 uint8_t iv [32 ] = {0 }; // only 16 bytes needed for IV.
7232#ifdef TESTING
7333 cipher_mock_iv (iv );
7434#else
7535 random_32_bytes (iv );
7636#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 );
15943 return true;
160- error :
161- util_zero (dec_pad , sizeof (dec_pad ));
162- util_zero (& ctx , sizeof (ctx ));
163- return false;
16444}
16545
16646bool cipher_aes_hmac_decrypt (
@@ -170,38 +50,9 @@ bool cipher_aes_hmac_decrypt(
17050 size_t * out_len ,
17151 const uint8_t * key )
17252{
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 );
20758}
0 commit comments