2424#include "aes.h"
2525#include "cipher.h"
2626#include "info.h"
27-
27+ #include "algorithms_cipher.h"
2828
2929ErlNifResourceType * aead_cipher_ctx_rtype ;
3030
3131struct aead_cipher_ctx {
32- const struct cipher_type_t * cipherp ;
32+ const cipher_type_C * cipherp ;
3333 EVP_CIPHER_CTX * ctx ;
3434
3535 ERL_NIF_TERM key ;
@@ -71,6 +71,7 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
7171 struct aead_cipher_ctx * ctx_res = NULL ;
7272 ERL_NIF_TERM ret , encflg_arg , type ;
7373 ErlNifBinary key ;
74+ struct cipher_type_flags_t flags ;
7475
7576 if ((ctx_res = enif_alloc_resource (aead_cipher_ctx_rtype , sizeof (struct aead_cipher_ctx ))) == NULL )
7677 return EXCP_ERROR (env , "Can't allocate resource" );
@@ -107,11 +108,13 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
107108
108109 if ((ctx_res -> cipherp = get_cipher_type (type , key .size )) == NULL )
109110 {ret = EXCP_BADARG_N (env , 0 , "Unknown cipher or invalid key size" ); goto done ;}
110- if (ctx_res -> cipherp -> flags & NON_EVP_CIPHER )
111+
112+ flags = get_cipher_type_flags (ctx_res -> cipherp );
113+ if (flags .non_evp_cipher )
111114 {ret = EXCP_BADARG_N (env , 0 , "Bad cipher" ); goto done ;}
112- if (! ( ctx_res -> cipherp -> flags & AEAD_CIPHER ) )
115+ if (!flags . aead_cipher )
113116 {ret = EXCP_BADARG_N (env , 0 , "Not aead cipher" ); goto done ;}
114- if (CIPHER_FORBIDDEN_IN_FIPS (ctx_res -> cipherp ))
117+ if (is_cipher_forbidden_in_fips (ctx_res -> cipherp ))
115118 {ret = EXCP_NOTSUP_N (env , 0 , "Forbidden in FIPS" ); goto done ;}
116119
117120#if defined(HAVE_GCM_EVP_DECRYPT_BUG )
@@ -120,13 +123,19 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
120123 }
121124#endif
122125
123- if (ctx_res -> cipherp -> cipher .p == NULL )
124- {ret = EXCP_NOTSUP_N (env , 0 , "The cipher is not supported in this libcrypto version" ); goto done ;}
125-
126- if ((ctx_res -> ctx = EVP_CIPHER_CTX_new ()) == NULL )
127- {ret = EXCP_ERROR (env , "Can't allocate ctx" ); goto done ;}
128- if (EVP_CipherInit_ex (ctx_res -> ctx , ctx_res -> cipherp -> cipher .p , NULL , NULL , NULL , ctx_res -> encflg ) != 1 )
129- {ret = EXCP_ERROR (env , "CipherInit failed" ); goto done ;}
126+ if (get_cipher_type_resource (ctx_res -> cipherp ) == NULL ) {
127+ ret = EXCP_NOTSUP_N (env , 0 , "The cipher is not supported in this libcrypto version" );
128+ goto done ;
129+ }
130+ if ((ctx_res -> ctx = EVP_CIPHER_CTX_new ()) == NULL ) {
131+ ret = EXCP_ERROR (env , "Can't allocate ctx" );
132+ goto done ;
133+ }
134+ if (EVP_CipherInit_ex (ctx_res -> ctx , get_cipher_type_resource (ctx_res -> cipherp ),
135+ NULL , NULL , NULL , ctx_res -> encflg ) != 1 ) {
136+ ret = EXCP_ERROR (env , "CipherInit failed" );
137+ goto done ;
138+ }
130139
131140 ret = enif_make_resource (env , ctx_res );
132141
@@ -146,9 +155,11 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
146155 const EVP_CIPHER * cipher = NULL ;
147156 ErlNifBinary key , iv , aad , in , tag ;
148157 unsigned int tag_len ;
149- unsigned char * outp , * tagp , * tag_data , * in_data ;
158+ unsigned char * outp , * tag_data , * in_data ;
150159 ERL_NIF_TERM type , out , out_tag , ret , encflg_arg ;
151160 int len , encflg , in_len ;
161+ struct cipher_type_flags_t flags ;
162+ struct cipher_type_aead_t aead ;
152163
153164 if (argc == 7 ) {
154165 /*
@@ -202,29 +213,45 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
202213 || iv .size > INT_MAX
203214 || in .size > INT_MAX
204215 || aad .size > INT_MAX )
205- {ret = EXCP_BADARG_N (env , 5 , "binary too long" ); goto done ;}
216+ {ret = EXCP_BADARG_N (env , 5 , "binary too long" ); goto done ;
217+ }
218+
219+ if ((cipherp = get_cipher_type (type , key .size )) == NULL ) {
220+ ret = EXCP_BADARG_N (env , 0 , "Unknown cipher or invalid key size" );
221+ goto done ;
222+ }
206223
207- if ((cipherp = get_cipher_type (type , key .size )) == NULL )
208- {ret = EXCP_BADARG_N (env , 0 , "Unknown cipher or invalid key size" ); goto done ;}
209- if (cipherp -> flags & NON_EVP_CIPHER )
210- {ret = EXCP_BADARG_N (env , 0 , "Bad cipher" ); goto done ;}
211- if (! (cipherp -> flags & AEAD_CIPHER ) )
212- {ret = EXCP_BADARG_N (env , 0 , "Not aead cipher" ); goto done ;}
213- if (CIPHER_FORBIDDEN_IN_FIPS (cipherp ))
214- {ret = EXCP_NOTSUP_N (env , 0 , "Forbidden in FIPS" ); goto done ;}
224+ flags = get_cipher_type_flags (cipherp );
225+ if (flags .non_evp_cipher ) {
226+ ret = EXCP_BADARG_N (env , 0 , "Bad cipher" );
227+ goto done ;
228+ }
229+ if (!flags .aead_cipher ) {
230+ ret = EXCP_BADARG_N (env , 0 , "Not aead cipher" );
231+ goto done ;
232+ }
233+ if (is_cipher_forbidden_in_fips (cipherp )) {
234+ ret = EXCP_NOTSUP_N (env , 0 , "Forbidden in FIPS" );
235+ goto done ;
236+ }
215237
216238#if defined(HAVE_GCM_EVP_DECRYPT_BUG )
217239 if ( !encflg && (cipherp -> flags & GCM_MODE )) {
218240 return aes_gcm_decrypt_NO_EVP (env , argc , argv );
219241 }
220242#endif
221- if ((cipher = cipherp -> cipher .p ) == NULL )
222- {ret = EXCP_NOTSUP_N (env , 0 , "The cipher is not supported in this libcrypto version" ); goto done ;}
223-
224- if ((ctx = EVP_CIPHER_CTX_new ()) == NULL )
225- {ret = EXCP_ERROR (env , "Can't allocate ctx" ); goto done ;}
226- if (EVP_CipherInit_ex (ctx , cipher , NULL , NULL , NULL , encflg ) != 1 )
227- {ret = EXCP_ERROR (env , "CipherInit failed" ); goto done ;}
243+ if ((cipher = get_cipher_type_resource (cipherp )) == NULL ) {
244+ ret = EXCP_NOTSUP_N (env , 0 , "The cipher is not supported in this libcrypto version" );
245+ goto done ;
246+ }
247+ if ((ctx = EVP_CIPHER_CTX_new ()) == NULL ) {
248+ ret = EXCP_ERROR (env , "Can't allocate ctx" );
249+ goto done ;
250+ }
251+ if (EVP_CipherInit_ex (ctx , cipher , NULL , NULL , NULL , encflg ) != 1 ) {
252+ ret = EXCP_ERROR (env , "CipherInit failed" );
253+ goto done ;
254+ }
228255
229256 } else {
230257 /* argc = 4 {state, IV, InData, AAD } */
@@ -258,17 +285,20 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
258285 }
259286
260287 cipherp = ctx_res -> cipherp ;
261- cipher = cipherp -> cipher . p ;
288+ cipher = get_cipher_type_resource ( cipherp ) ;
262289 ctx = ctx_res -> ctx ;
263290 }
264291 /* Init done */
265292
266- if (EVP_CIPHER_CTX_ctrl (ctx , cipherp -> extra .aead .ctx_ctrl_set_ivlen , (int )iv .size , NULL ) != 1 )
293+ aead = get_cipher_type_aead (cipherp );
294+ flags = get_cipher_type_flags (cipherp );
295+
296+ if (EVP_CIPHER_CTX_ctrl (ctx , aead .ctx_ctrl_set_ivlen , (int )iv .size , NULL ) != 1 )
267297 {ret = EXCP_BADARG_N (env , 2 , "Bad IV length" ); goto done ;}
268298
269299#if defined(HAVE_CCM )
270- if (cipherp -> flags & CCM_MODE ) {
271- if (EVP_CIPHER_CTX_ctrl (ctx , cipherp -> extra . aead .ctx_ctrl_set_tag , (int )tag_len , tag_data ) != 1 )
300+ if (flags . ccm_mode ) {
301+ if (EVP_CIPHER_CTX_ctrl (ctx , aead .ctx_ctrl_set_tag , (int )tag_len , tag_data ) != 1 )
272302 {ret = EXCP_BADARG_N (env , 5 , "Can't set tag" ); goto done ;}
273303 if (EVP_CipherInit_ex (ctx , NULL , NULL , key .data , iv .data , -1 ) != 1 )
274304 {ret = EXCP_ERROR (env , "Can't set key or iv" ); goto done ;}
@@ -304,8 +334,8 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
304334 ret = atom_error ;
305335 goto done ;
306336 }
307- if (encflg )
308- {
337+ if (encflg ) {
338+ unsigned char * tagp ;
309339 if (argc == 7 ) {
310340 /* Finalize the encrypted text */
311341 if (EVP_CipherFinal_ex (ctx , outp , & len ) != 1 )
@@ -314,7 +344,7 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
314344 /* Get the tag */
315345 if ((tagp = enif_make_new_binary (env , tag_len , & out_tag )) == NULL )
316346 {ret = EXCP_ERROR (env , "Can't make 'Out' binary" ); goto done ;}
317- if (EVP_CIPHER_CTX_ctrl (ctx , cipherp -> extra . aead .ctx_ctrl_get_tag , (int )tag_len , tagp ) != 1 )
347+ if (EVP_CIPHER_CTX_ctrl (ctx , aead .ctx_ctrl_get_tag , (int )tag_len , tagp ) != 1 )
318348 {ret = EXCP_ERROR (env , "Can't get Tag" ); goto done ;}
319349
320350 /* Make the return value (the tuple with binary crypto text and the tag) */
@@ -324,7 +354,7 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
324354 {ret = EXCP_ERROR (env , "Encrypt error" ); goto done ;}
325355 /* Add tag to output end */
326356 tagp = outp + in_len ;
327- if (EVP_CIPHER_CTX_ctrl (ctx , cipherp -> extra . aead .ctx_ctrl_get_tag , (int )tag_len , tagp ) != 1 )
357+ if (EVP_CIPHER_CTX_ctrl (ctx , aead .ctx_ctrl_get_tag , (int )tag_len , tagp ) != 1 )
328358 {ret = EXCP_ERROR (env , "Can't get Tag" ); goto done ;}
329359 ret = out ;
330360 }
@@ -333,8 +363,8 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
333363 {
334364#if defined(HAVE_GCM ) || defined(HAVE_CHACHA20_POLY1305 )
335365 /* Check the Tag before returning. CCM_MODE does this previously. */
336- if (!( cipherp -> flags & CCM_MODE )) { /* That is, CHACHA20_POLY1305 or GCM_MODE */
337- if (EVP_CIPHER_CTX_ctrl (ctx , cipherp -> extra . aead .ctx_ctrl_set_tag , (int )tag_len , tag_data ) != 1 )
366+ if (!flags . ccm_mode ) { /* That is, CHACHA20_POLY1305 or GCM_MODE */
367+ if (EVP_CIPHER_CTX_ctrl (ctx , aead .ctx_ctrl_set_tag , (int )tag_len , tag_data ) != 1 )
338368 /* Decrypt error */
339369 {ret = atom_error ; goto done ;}
340370 /* CCM dislikes EVP_DecryptFinal_ex on decrypting for pre 1.1.1, so we do it only here */
0 commit comments