From fcc89ded7f5cb5f81533883c30e7daa89195970d Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 28 Feb 2019 19:59:30 +0100 Subject: crypto: Remove condition of block size Unnecessary, because the underlying crypto libraries handles this case. Also: - Relax the condition of binary Key and IV -Fix bug for empty data on historic cryptolibs because tests fails for empty data on at least aes_cfb8 on OpenSSL 0.9.8h. It does not fail on OpenSSL 0.9.8zh. --- lib/crypto/c_src/api_ng.c | 2 -- lib/crypto/src/crypto.erl | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index c4114d1626..f24aded748 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -165,8 +165,6 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ ASSERT(in_data_bin.size =< INT_MAX); block_size = EVP_CIPHER_CTX_block_size(ctx->ctx); - if (in_data_bin.size % (size_t)block_size != 0) - return ERROR_Str(env, "Data not a multiple of block size"); if (argc==3) { if (!enif_inspect_iolist_as_binary(env, argv[2], &ivec_bin)) diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 97a4a7a3f0..8d6d24210a 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -2252,15 +2252,15 @@ check_otp_test_engine(LibDir) -> | block_cipher_with_iv() | block_cipher_without_iv() , Key :: iodata(), - IV :: binary(), + IV :: iodata(), EncryptFlag :: boolean() | undefined, State :: crypto_state() . -crypto_init(Cipher, Key, IV, EncryptFlag) when is_atom(Cipher), - is_binary(Key), - is_binary(IV), - is_atom(EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), Key, IV, EncryptFlag) of +crypto_init(Cipher, Key, IV, EncryptFlag) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + EncryptFlag) of {error,Error} -> {error,Error}; undefined -> % For compatibility function crypto_stream_init/3 @@ -2284,8 +2284,13 @@ crypto_init(Cipher, Key, IV, EncryptFlag) when is_atom(Cipher), when State :: crypto_state(), Data :: iodata(), Result :: binary() | {crypto_state(),binary()}. -crypto_update(State, Data) -> - mk_ret(ng_crypto_update_nif(State, Data)). +crypto_update(State, Data0) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + mk_ret(ng_crypto_update_nif(State, Data)) + end. %%%---------------------------------------------------------------- %%% -- cgit v1.2.3 From 26754483d39dab9ab09f69fcecb89ab1fb5135bd Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 22 Feb 2019 19:06:34 +0100 Subject: crypto: Implement crypto one-shot Also: Compatibility functions for aes_ctr in historic crypto libs --- lib/crypto/c_src/api_ng.c | 432 ++++++++++++++++++++++++++++++++-------------- lib/crypto/c_src/api_ng.h | 1 + lib/crypto/c_src/cipher.c | 9 +- lib/crypto/c_src/cipher.h | 4 + lib/crypto/c_src/crypto.c | 2 +- lib/crypto/src/crypto.erl | 106 +++--------- 6 files changed, 342 insertions(+), 212 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index f24aded748..c3f5ee0bea 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -29,6 +29,7 @@ * */ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -36,186 +37,367 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ #define ERROR_Term(Env, ReasonTerm) enif_make_tuple2((Env), atom_error, (ReasonTerm)) #define ERROR_Str(Env, ReasonString) ERROR_Term((Env), enif_make_string((Env),(ReasonString),(ERL_NIF_LATIN1))) -/* Initializes state for (de)encryption - */ -ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Cipher, Key, IVec, Encrypt) % if no IV for the Cipher, set IVec = <<>> - */ - ErlNifBinary key_bin, ivec_bin; - unsigned char *iv = NULL; - struct evp_cipher_ctx *ctx; - const struct cipher_type_t *cipherp; - const EVP_CIPHER *cipher; - ERL_NIF_TERM enc_flg_arg, ret; - int enc; - unsigned iv_len; - - enc_flg_arg = argv[argc-1]; - if (enc_flg_arg == atom_true) - enc = 1; - else if (enc_flg_arg == atom_false) - enc = 0; - else if (enc_flg_arg == atom_undefined) + +#ifdef HAVE_ECB_IVEC_BUG + /* <= 0.9.8l returns faulty ivec length */ +# define GET_IV_LEN(Ciph) ((Ciph)->flags & ECB_BUG_0_9_8L) ? 0 : EVP_CIPHER_iv_length((Ciph)->cipher.p) +#else +# define GET_IV_LEN(Ciph) EVP_CIPHER_iv_length((Ciph)->cipher.p) +#endif + +/*************************************************************************/ +/* Get the arguments for the initialization of the EVP_CIPHER_CTX. Check */ +/* them and initialize that context. */ +/*************************************************************************/ +static int get_init_args(ErlNifEnv* env, + struct evp_cipher_ctx *ctx_res, + const ERL_NIF_TERM cipher_arg, + const ERL_NIF_TERM key_arg, + const ERL_NIF_TERM ivec_arg, + const ERL_NIF_TERM encflg_arg, + const struct cipher_type_t **cipherp, + ERL_NIF_TERM *return_term) +{ + int ivec_len; + ErlNifBinary key_bin; + ErlNifBinary ivec_bin; + int encflg; + + ctx_res->ctx = NULL; /* For testing if *ctx should be freed after errors */ + + /* Fetch the flag telling if we are going to encrypt (=true) or decrypt (=false) */ + if (encflg_arg == atom_true) + encflg = 1; + else if (encflg_arg == atom_false) + encflg = 0; + else if (encflg_arg == atom_undefined) /* For compat funcs in crypto.erl */ - enc = -1; + encflg = -1; else - return ERROR_Str(env, "Bad enc flag"); - - if (!enif_inspect_binary(env, argv[1], &key_bin)) - return ERROR_Str(env, "Bad key"); + { + *return_term = ERROR_Str(env, "Bad enc flag"); + goto err; + } - if (!(cipherp = get_cipher_type(argv[0], key_bin.size))) - return ERROR_Str(env, "Unknown cipher or bad key size"); + /* Fetch the key */ + if (!enif_inspect_iolist_as_binary(env, key_arg, &key_bin)) + { + *return_term = ERROR_Str(env, "Bad key"); + goto err; + } - if (FORBIDDEN_IN_FIPS(cipherp)) - return enif_raise_exception(env, atom_notsup); + /* Fetch cipher type */ + if (!enif_is_atom(env, cipher_arg)) + { + *return_term = ERROR_Str(env, "Cipher id is not an atom"); + goto err; + } - if (enc == -1) - return atom_undefined; + if (!(*cipherp = get_cipher_type(cipher_arg, key_bin.size))) + { + *return_term = ERROR_Str(env, "Unknown cipher or bad key size for the cipher"); + goto err; + } - if (!(cipher = cipherp->cipher.p)) { + if (FORBIDDEN_IN_FIPS(*cipherp)) + { + *return_term = enif_raise_exception(env, atom_notsup); + goto err; + } + + /* Fetch IV */ #if !defined(HAVE_EVP_AES_CTR) - if (cipherp->flags & AES_CTR_COMPAT) - return aes_ctr_stream_init_compat(env, argv[1], argv[2]); - else -#endif - return enif_raise_exception(env, atom_notsup); - } + /* This is code for OpenSSL 0.9.8. Therefore we could accept some ineficient code */ + ctx_res->env = NULL; + ctx_res->state = atom_undefined; -#ifdef HAVE_ECB_IVEC_BUG - if (cipherp->flags & ECB_BUG_0_9_8L) - iv_len = 0; /* <= 0.9.8l returns faulty ivec length */ + if (!((*cipherp)->cipher.p) && (*cipherp)->flags & AES_CTR_COMPAT) + ivec_len = 16; else #endif - iv_len = EVP_CIPHER_iv_length(cipher); + ivec_len = GET_IV_LEN(*cipherp); + + if (ivec_len) { + if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin)) + { + *return_term = ERROR_Str(env, "Bad iv type"); + goto err; + } + + if (ivec_len != ivec_bin.size) + { + *return_term = ERROR_Str(env, "Bad iv size"); + goto err; + } + } - if (iv_len) { - if (!enif_inspect_binary(env, argv[2], &ivec_bin)) - return ERROR_Str(env, "Bad iv type"); + if (!((*cipherp)->cipher.p)) + { +#if !defined(HAVE_EVP_AES_CTR) + if ((*cipherp)->flags & AES_CTR_COMPAT) + { + ERL_NIF_TERM ecount_bin; + unsigned char *outp; + if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) { + *return_term = ERROR_Str(env, "Can't allocate ecount_bin"); + goto err; + } + memset(outp, 0, AES_BLOCK_SIZE); + + ctx_res->env = enif_alloc_env(); + if (!ctx_res->env) { + *return_term = ERROR_Str(env, "Can't allocate env"); + goto err; + } + ctx_res->state = + enif_make_copy(ctx_res->env, + enif_make_tuple4(env, key_arg, ivec_arg, ecount_bin, enif_make_int(env, 0))); + goto success; + } +#endif + *return_term = enif_raise_exception(env, atom_notsup); + goto err; + } - if (iv_len != ivec_bin.size) - return ERROR_Str(env, "Bad iv size"); + if (encflg == -1) + { + *return_term = atom_undefined; + goto err; // Yes... + } - iv = ivec_bin.data; - } + /* Initialize the EVP_CIPHER_CTX */ - if ((ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - return ERROR_Str(env, "Can't allocate resource"); + ctx_res->ctx = EVP_CIPHER_CTX_new(); + if (! ctx_res->ctx) + { + *return_term = ERROR_Str(env, "Can't allocate context"); + goto err; + } - ctx->ctx = EVP_CIPHER_CTX_new(); - if (! ctx->ctx) - return ERROR_Str(env, "Can't allocate context"); + if (!EVP_CipherInit_ex(ctx_res->ctx, (*cipherp)->cipher.p, NULL, NULL, NULL, encflg)) + { + *return_term = ERROR_Str(env, "Can't initialize context, step 1"); + goto err; + } - if (!EVP_CipherInit_ex(ctx->ctx, cipher, NULL, NULL, NULL, enc)) { - enif_release_resource(ctx); - return ERROR_Str(env, "Can't initialize context, step 1"); - } + if (!EVP_CIPHER_CTX_set_key_length(ctx_res->ctx, (int)key_bin.size)) + { + *return_term = ERROR_Str(env, "Can't initialize context, key_length"); + goto err; + } - if (!EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)key_bin.size)) { - enif_release_resource(ctx); - return ERROR_Str(env, "Can't initialize context, key_length"); - } - if (EVP_CIPHER_type(cipher) == NID_rc2_cbc) { + if (EVP_CIPHER_type((*cipherp)->cipher.p) == NID_rc2_cbc) { if (key_bin.size > INT_MAX / 8) { - enif_release_resource(ctx); - return ERROR_Str(env, "To large rc2_cbc key"); + *return_term = ERROR_Str(env, "To large rc2_cbc key"); + goto err; } - if (!EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_SET_RC2_KEY_BITS, (int)key_bin.size * 8, NULL)) { - enif_release_resource(ctx); - return ERROR_Str(env, "ctrl rc2_cbc key"); + if (!EVP_CIPHER_CTX_ctrl(ctx_res->ctx, EVP_CTRL_SET_RC2_KEY_BITS, (int)key_bin.size * 8, NULL)) { + *return_term = ERROR_Str(env, "ctrl rc2_cbc key"); + goto err; } } - if (!EVP_CipherInit_ex(ctx->ctx, NULL, NULL, key_bin.data, iv, enc)) { - enif_release_resource(ctx); - return ERROR_Str(env, "Can't initialize key and/or iv"); + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, encflg)) { + *return_term = ERROR_Str(env, "Can't initialize key and/or iv"); + goto err; } - EVP_CIPHER_CTX_set_padding(ctx->ctx, 0); - - ret = enif_make_resource(env, ctx); - enif_release_resource(ctx); - return ret; -} + EVP_CIPHER_CTX_set_padding(ctx_res->ctx, 0); -ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Context, Data) - (Context, Data, IV) */ - struct evp_cipher_ctx *ctx; - ErlNifBinary in_data_bin, ivec_bin, out_data_bin; - int out_len, block_size; + *return_term = atom_ok; #if !defined(HAVE_EVP_AES_CTR) - const ERL_NIF_TERM *state_term; - int state_arity; - - if (enif_get_tuple(env, argv[0], &state_arity, &state_term) && (state_arity == 4)) { - return aes_ctr_stream_encrypt_compat(env, argv[0], argv[1]); - } + success: #endif + return 1; - if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx)) - return ERROR_Str(env, "Bad 1:st arg"); - - if (!enif_inspect_binary(env, argv[1], &in_data_bin) ) - return ERROR_Str(env, "Bad 2:nd arg"); + err: + if (ctx_res->ctx) EVP_CIPHER_CTX_free(ctx_res->ctx); + return 0; +} + +/*************************************************************************/ +/* Get the arguments for the EVP_CipherUpdate function, and call it. */ +/*************************************************************************/ + +static int get_update_args(ErlNifEnv* env, + struct evp_cipher_ctx *ctx_res, + const ERL_NIF_TERM indata_arg, + ERL_NIF_TERM *return_term) +{ + ErlNifBinary in_data_bin, out_data_bin; + int out_len, block_size; + + if (!enif_inspect_binary(env, indata_arg, &in_data_bin) ) + { + *return_term = ERROR_Str(env, "Bad 2:nd arg"); + goto err; + } - /* arg[1] was checked by the caller */ ASSERT(in_data_bin.size =< INT_MAX); - block_size = EVP_CIPHER_CTX_block_size(ctx->ctx); - - if (argc==3) { - if (!enif_inspect_iolist_as_binary(env, argv[2], &ivec_bin)) - return ERROR_Str(env, "Not binary IV"); - - if (ivec_bin.size > INT_MAX) - return ERROR_Str(env, "Too big IV"); - - if (!EVP_CipherInit_ex(ctx->ctx, NULL, NULL, NULL, ivec_bin.data, -1)) - return ERROR_Str(env, "Can't set IV"); +#if !defined(HAVE_EVP_AES_CTR) + // enif_fprintf(stdout, "%s:%u state = %T\r\n", __FILE__, __LINE__, ctx_res->state); + if (ctx_res->state != atom_undefined) { + ERL_NIF_TERM state0, newstate_and_outdata; + const ERL_NIF_TERM *tuple_argv; + int tuple_argc; + + state0 = enif_make_copy(env, ctx_res->state); + + if (enif_get_tuple(env, state0, &tuple_argc, &tuple_argv) && (tuple_argc == 4)) { + /* A compatibility state term */ + /* encrypt and decrypt is performed by calling the same function */ + newstate_and_outdata = aes_ctr_stream_encrypt_compat(env, state0, indata_arg); + + if (enif_get_tuple(env, newstate_and_outdata, &tuple_argc, &tuple_argv) && (tuple_argc == 2)) { + /* newstate_and_outdata = {NewState, OutData} */ + ctx_res->state = enif_make_copy(ctx_res->env, tuple_argv[0]); + *return_term = tuple_argv[1]; + } + } + } else +#endif + { + block_size = EVP_CIPHER_CTX_block_size(ctx_res->ctx); + + if (!enif_alloc_binary((size_t)in_data_bin.size+block_size, &out_data_bin)) + { + *return_term = ERROR_Str(env, "Can't allocate outdata"); + goto err; + } + + if (!EVP_CipherUpdate(ctx_res->ctx, out_data_bin.data, &out_len, in_data_bin.data, in_data_bin.size)) + { + *return_term = ERROR_Str(env, "Can't update"); + goto err; + } + + if (!enif_realloc_binary(&out_data_bin, (size_t)out_len)) + { + *return_term = ERROR_Str(env, "Can't reallocate"); + goto err; + } + + CONSUME_REDS(env, in_data_bin); + *return_term = enif_make_binary(env, &out_data_bin); } - if (!enif_alloc_binary((size_t)in_data_bin.size+block_size, &out_data_bin)) - return ERROR_Str(env, "Can't allocate outdata"); + /* success: */ + return 1; + + err: + return 0; +} + +/*************************************************************************/ +/* Initialize the state for (de/en)cryption */ +/*************************************************************************/ + +ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Cipher, Key, IVec, Encrypt) % if no IV for the Cipher, set IVec = <<>> + */ + struct evp_cipher_ctx *ctx_res = NULL; + const struct cipher_type_t *cipherp; + ERL_NIF_TERM ret; + + if ((ctx_res = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) + return ERROR_Str(env, "Can't allocate resource"); + + if (!get_init_args(env, ctx_res, argv[0], argv[1], argv[2], argv[argc-1], + &cipherp, &ret)) + /* Error msg in &ret */ + goto ret; + + ret = enif_make_resource(env, ctx_res); + if(ctx_res) enif_release_resource(ctx_res); + ret: + return ret; +} + - if (!EVP_CipherUpdate(ctx->ctx, out_data_bin.data, &out_len, in_data_bin.data, in_data_bin.size)) - return ERROR_Str(env, "Can't update"); +/*************************************************************************/ +/* Encrypt/decrypt */ +/*************************************************************************/ - if (!enif_realloc_binary(&out_data_bin, (size_t)out_len)) - return ERROR_Str(env, "Can't reallocate"); - CONSUME_REDS(env, in_data_bin); - return enif_make_binary(env, &out_data_bin); +ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ + struct evp_cipher_ctx *ctx_res; + ERL_NIF_TERM ret; + + if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res)) + return ERROR_Str(env, "Bad 1:st arg"); + + get_update_args(env, ctx_res, argv[1], &ret); + + return ret; /* Both success and error */ } ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Context, Data) - (Context, Data, IV) */ - int i; +{/* (Context, Data) */ ErlNifBinary data_bin; - ERL_NIF_TERM new_argv[3]; ASSERT(argc =< 3); - if (!enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) - return ERROR_Str(env, "iodata expected as data"); + if (!enif_inspect_binary(env, argv[1], &data_bin)) + return ERROR_Str(env, "expected binary as data"); if (data_bin.size > INT_MAX) return ERROR_Str(env, "to long data"); - for (i=0; i MAX_BYTES_TO_NIF) { return enif_schedule_nif(env, "ng_crypto_update", ERL_NIF_DIRTY_JOB_CPU_BOUND, - ng_crypto_update, argc, new_argv); + ng_crypto_update, argc, argv); } - return ng_crypto_update(env, argc, new_argv); + return ng_crypto_update(env, argc, argv); } +/*************************************************************************/ +/* One shot */ +/*************************************************************************/ + +ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Cipher, Key, IVec, Data, Encrypt) */ + struct evp_cipher_ctx ctx_res; + const struct cipher_type_t *cipherp; + ERL_NIF_TERM ret; + + if (!get_init_args(env, &ctx_res, argv[0], argv[1], argv[2], argv[4], &cipherp, &ret)) + goto ret; + + get_update_args(env, &ctx_res, argv[3], &ret); + + ret: + if (ctx_res.ctx) + EVP_CIPHER_CTX_free(ctx_res.ctx); + return ret; +} + +ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Cipher, Key, IVec, Data, Encrypt) % if no IV for the Cipher, set IVec = <<>> + */ + ErlNifBinary data_bin; + + ASSERT(argc == 5); + + if (!enif_inspect_binary(env, argv[3], &data_bin)) + return ERROR_Str(env, "expected binary as data"); + + if (data_bin.size > INT_MAX) + return ERROR_Str(env, "to long data"); + + /* Run long jobs on a dirty scheduler to not block the current emulator thread */ + if (data_bin.size > MAX_BYTES_TO_NIF) { + return enif_schedule_nif(env, "ng_crypto_one_shot", + ERL_NIF_DIRTY_JOB_CPU_BOUND, + ng_crypto_one_shot, argc, argv); + } + + return ng_crypto_one_shot(env, argc, argv); +} diff --git a/lib/crypto/c_src/api_ng.h b/lib/crypto/c_src/api_ng.h index a3b40fe7fc..5c7d9af3c5 100644 --- a/lib/crypto/c_src/api_ng.h +++ b/lib/crypto/c_src/api_ng.h @@ -25,5 +25,6 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); #endif /* E_AES_H__ */ diff --git a/lib/crypto/c_src/cipher.c b/lib/crypto/c_src/cipher.c index c055a62654..5c57898c50 100644 --- a/lib/crypto/c_src/cipher.c +++ b/lib/crypto/c_src/cipher.c @@ -98,7 +98,9 @@ static struct cipher_type_t cipher_types[] = {{"aes_128_ctr"}, {NULL}, 16, AES_CTR_COMPAT}, {{"aes_192_ctr"}, {NULL}, 24, AES_CTR_COMPAT}, {{"aes_256_ctr"}, {NULL}, 32, AES_CTR_COMPAT}, - {{"aes_ctr"}, {NULL}, 0, AES_CTR_COMPAT}, + {{"aes_ctr"}, {NULL}, 16, AES_CTR_COMPAT}, + {{"aes_ctr"}, {NULL}, 24, AES_CTR_COMPAT}, + {{"aes_ctr"}, {NULL}, 32, AES_CTR_COMPAT}, #endif #if defined(HAVE_CHACHA20) @@ -162,6 +164,11 @@ static void evp_cipher_ctx_dtor(ErlNifEnv* env, struct evp_cipher_ctx* ctx) { if (ctx->ctx) EVP_CIPHER_CTX_free(ctx->ctx); + +#if !defined(HAVE_EVP_AES_CTR) + if (ctx->env) + enif_free_env(ctx->env); +#endif } int init_cipher_ctx(ErlNifEnv *env) { diff --git a/lib/crypto/c_src/cipher.h b/lib/crypto/c_src/cipher.h index b0d9d324e1..f7b1a09f21 100644 --- a/lib/crypto/c_src/cipher.h +++ b/lib/crypto/c_src/cipher.h @@ -59,6 +59,10 @@ struct cipher_type_t { extern ErlNifResourceType* evp_cipher_ctx_rtype; struct evp_cipher_ctx { EVP_CIPHER_CTX* ctx; +#if !defined(HAVE_EVP_AES_CTR) + ErlNifEnv* env; + ERL_NIF_TERM state; +#endif }; ERL_NIF_TERM cipher_info_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 261590d9a5..c6a5dde67f 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -88,7 +88,7 @@ static ErlNifFunc nif_funcs[] = { {"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt, 0}, {"ng_crypto_init_nif", 4, ng_crypto_init_nif, 0}, {"ng_crypto_update_nif", 2, ng_crypto_update_nif, 0}, - {"ng_crypto_update_nif", 3, ng_crypto_update_nif, 0}, + {"ng_crypto_one_shot_nif", 5, ng_crypto_one_shot_nif, 0}, {"strong_rand_bytes_nif", 1, strong_rand_bytes_nif, 0}, {"strong_rand_range_nif", 1, strong_rand_range_nif, 0}, {"rand_uniform_nif", 2, rand_uniform_nif, 0}, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 8d6d24210a..96213fa6e6 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -51,13 +51,13 @@ %% Experiment -export([crypto_init/4, - crypto_update/2, crypto_update/3, + crypto_update/2, + crypto_one_shot/5, + %% Emulates old api: crypto_stream_init/2, crypto_stream_init/3, crypto_stream_encrypt/2, - crypto_stream_decrypt/2, - crypto_block_encrypt/3, crypto_block_encrypt/4, - crypto_block_decrypt/3, crypto_block_decrypt/4 + crypto_stream_decrypt/2 ]). @@ -556,11 +556,6 @@ cipher_info(Type) -> block_encrypt(Type, Key, Ivec, Data) -> do_block_encrypt(alias(Type), Key, Ivec, Data). -do_block_encrypt(Type, Key0, Ivec, Data) when Type =:= des_ede3_cbc; - Type =:= des_ede3_cfb -> - Key = check_des3_key(Key0), - block_crypt_nif(Type, Key, Ivec, Data, true); - do_block_encrypt(Type, Key, Ivec, PlainText) when Type =:= aes_ige256 -> notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true)); @@ -577,14 +572,13 @@ do_block_encrypt(Type, Key, Ivec, Data) when Type =:= aes_gcm; end; do_block_encrypt(Type, Key, Ivec, PlainText) -> - block_crypt_nif(Type, Key, Ivec, PlainText, true). - + crypto_one_shot(Type, Key, Ivec, PlainText, true). -spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). block_encrypt(Type, Key, PlainText) -> - block_crypt_nif(alias(Type), Key, PlainText, true). + crypto_one_shot(Type, Key, <<>>, PlainText, true). %%%---------------------------------------------------------------- %%%---------------------------------------------------------------- @@ -595,11 +589,6 @@ block_encrypt(Type, Key, PlainText) -> block_decrypt(Type, Key, Ivec, Data) -> do_block_decrypt(alias(Type), Key, Ivec, Data). -do_block_decrypt(Type, Key0, Ivec, Data) when Type =:= des_ede3_cbc; - Type =:= des_ede3_cfb -> - Key = check_des3_key(Key0), - block_crypt_nif(Type, Key, Ivec, Data, false); - do_block_decrypt(aes_ige256, Key, Ivec, Data) -> notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false)); @@ -609,14 +598,13 @@ do_block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm; aead_decrypt(Type, Key, Ivec, AAD, Data, Tag); do_block_decrypt(Type, Key, Ivec, Data) -> - block_crypt_nif(Type, Key, Ivec, Data, false). - + crypto_one_shot(Type, Key, Ivec, Data, false). -spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). block_decrypt(Type, Key, Data) -> - block_crypt_nif(alias(Type), Key, Data, false). + crypto_one_shot(Type, Key, <<>>, Data, false). %%%---------------------------------------------------------------- -spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, @@ -1785,19 +1773,6 @@ poly1305_nif(_Key, _Data) -> ?nif_stub. cipher_info_nif(_Type) -> ?nif_stub. -block_crypt_nif(_Type, _Key, _Ivec, _Text, _IsEncrypt) -> ?nif_stub. -block_crypt_nif(_Type, _Key, _Text, _IsEncrypt) -> ?nif_stub. - -check_des3_key(Key) -> - case lists:map(fun erlang:iolist_to_binary/1, Key) of - ValidKey = [B1, B2, B3] when byte_size(B1) =:= 8, - byte_size(B2) =:= 8, - byte_size(B3) =:= 8 -> - ValidKey; - _ -> - error(badarg) - end. - %% %% AES - in Galois/Counter Mode (GCM) %% @@ -2289,67 +2264,29 @@ crypto_update(State, Data0) -> <<>> -> <<>>; % Known to fail on OpenSSL 0.9.8h Data -> - mk_ret(ng_crypto_update_nif(State, Data)) + ng_crypto_update_nif(State, Data) end. -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt a sequence of bytes but change the IV first. -%%% Not applicable for all modes. -%%% - --spec crypto_update(State, Data, IV) -> {ok,Result} | {error,term()} - when State :: crypto_state(), - Data :: iodata(), - IV :: binary(), - Result :: binary() | {crypto_state(),binary()}. -crypto_update(State, Data, IV) -> - mk_ret(ng_crypto_update_nif(State, Data, IV)). - -%%%---------------------------------------------------------------- -%%% Helpers -mk_ret(R) -> mk_ret(R, []). - -mk_ret({error,Error}, _) -> - {error,Error}; -mk_ret(Bin, Acc) when is_binary(Bin) -> - {ok, iolist_to_binary(lists:reverse([Bin|Acc]))}; -mk_ret({State1,Bin}, Acc) when is_tuple(State1), - size(State1) == 4, - is_binary(Bin) -> - %% compatibility with old cryptolibs < 1.0.1 - {ok, {State1, iolist_to_binary(lists:reverse([Bin|Acc]))}}. - %%%---------------------------------------------------------------- %%% NIFs + ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. + +%% _Data MUST be binary() ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub. + +%% _Data MUST be binary() +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%================================================================ %%% Compatibility functions to be called by "old" api functions. -%%%-------------------------------- -%%%---- block encrypt/decrypt -crypto_block_encrypt(Cipher, Key, Data) -> crypto_block_encrypt(Cipher, Key, <<>>, Data). -crypto_block_decrypt(Cipher, Key, Data) -> crypto_block_decrypt(Cipher, Key, <<>>, Data). - -crypto_block_encrypt(Cipher, Key, Ivec, Data) -> crypto_block(Cipher, Key, Ivec, Data, true). -crypto_block_decrypt(Cipher, Key, Ivec, Data) -> crypto_block(Cipher, Key, Ivec, Data, false). - -%% AEAD: use old funcs - -%%%---- helper -crypto_block(Cipher, Key, IV, Data, EncryptFlag) -> - case crypto_init(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag) of - {ok, Ref} -> - case crypto_update(Ref, Data) of - {ok, {_,Bin}} when is_binary(Bin) -> Bin; - {ok, Bin} when is_binary(Bin) -> Bin; - {error,_} -> error(badarg) - end; - - {error,_} -> error(badarg) +crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) end. %%%-------------------------------- @@ -2391,7 +2328,6 @@ crypto_stream_emulate({Cipher,State}, Data, _) -> {error,_} -> error(badarg) end. - %%%================================================================ prepend_cipher_aliases(L) -> -- cgit v1.2.3 From c417b9d8b1959b0c18030d08efe5a9abdc86dc10 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Mar 2019 10:50:48 +0100 Subject: crypto: Fix syntax error in ASSERT --- lib/crypto/c_src/api_ng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index c3f5ee0bea..50c0e9fcf6 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -235,7 +235,7 @@ static int get_update_args(ErlNifEnv* env, goto err; } - ASSERT(in_data_bin.size =< INT_MAX); + ASSERT(in_data_bin.size <= INT_MAX); #if !defined(HAVE_EVP_AES_CTR) // enif_fprintf(stdout, "%s:%u state = %T\r\n", __FILE__, __LINE__, ctx_res->state); @@ -340,7 +340,7 @@ ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a {/* (Context, Data) */ ErlNifBinary data_bin; - ASSERT(argc =< 3); + ASSERT(argc <= 3); if (!enif_inspect_binary(env, argv[1], &data_bin)) return ERROR_Str(env, "expected binary as data"); -- cgit v1.2.3 From 18124e1cf2157222fb91660fa0d0e46a75309c75 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 5 Mar 2019 11:36:09 +0100 Subject: crypto: Remove block.c and block.h Replaced by api_ng.c --- lib/crypto/c_src/Makefile.in | 1 - lib/crypto/c_src/block.c | 149 ------------------------------------------- lib/crypto/c_src/block.h | 28 -------- lib/crypto/c_src/crypto.c | 3 - 4 files changed, 181 deletions(-) delete mode 100644 lib/crypto/c_src/block.c delete mode 100644 lib/crypto/c_src/block.h (limited to 'lib') diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index e1e7f71538..89de220e7b 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -77,7 +77,6 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \ $(OBJDIR)/algorithms$(TYPEMARKER).o \ $(OBJDIR)/api_ng$(TYPEMARKER).o \ $(OBJDIR)/atoms$(TYPEMARKER).o \ - $(OBJDIR)/block$(TYPEMARKER).o \ $(OBJDIR)/bn$(TYPEMARKER).o \ $(OBJDIR)/chacha20$(TYPEMARKER).o \ $(OBJDIR)/cipher$(TYPEMARKER).o \ diff --git a/lib/crypto/c_src/block.c b/lib/crypto/c_src/block.c deleted file mode 100644 index 0a4fd72623..0000000000 --- a/lib/crypto/c_src/block.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#include "block.h" -#include "aes.h" -#include "cipher.h" - -ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Type, Key, Ivec, Text, IsEncrypt) or (Type, Key, Text, IsEncrypt) */ - const struct cipher_type_t *cipherp; - const EVP_CIPHER *cipher; - ErlNifBinary key, ivec, text; - EVP_CIPHER_CTX *ctx = NULL; - ERL_NIF_TERM ret; - unsigned char *out; - int ivec_size, out_size = 0; - int cipher_len; - - ASSERT(argc == 4 || argc == 5); - - if (!enif_inspect_iolist_as_binary(env, argv[1], &key)) - goto bad_arg; - if (key.size > INT_MAX) - goto bad_arg; - if ((cipherp = get_cipher_type(argv[0], key.size)) == NULL) - goto bad_arg; - if (cipherp->flags & (NON_EVP_CIPHER | AEAD_CIPHER)) - goto bad_arg; - if (!enif_inspect_iolist_as_binary(env, argv[argc - 2], &text)) - goto bad_arg; - if (text.size > INT_MAX) - goto bad_arg; - - if (FORBIDDEN_IN_FIPS(cipherp)) - return enif_raise_exception(env, atom_notsup); - if ((cipher = cipherp->cipher.p) == NULL) - return enif_raise_exception(env, atom_notsup); - - if (cipherp->flags & AES_CFBx) { - if (argv[0] == atom_aes_cfb8 - && (key.size == 24 || key.size == 32)) { - /* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes? - * Fall back on low level API - */ - return aes_cfb_8_crypt(env, argc-1, argv+1); - } - else if (argv[0] == atom_aes_cfb128 - && (key.size == 24 || key.size == 32)) { - /* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes? - * Fall back on low level API - */ - return aes_cfb_128_crypt_nif(env, argc-1, argv+1); - } - } - - ivec_size = EVP_CIPHER_iv_length(cipher); - -#ifdef HAVE_ECB_IVEC_BUG - if (cipherp->flags & ECB_BUG_0_9_8L) - ivec_size = 0; /* 0.9.8l returns faulty ivec_size */ -#endif - - if (ivec_size < 0) - goto bad_arg; - - if ((cipher_len = EVP_CIPHER_block_size(cipher)) < 0) - goto bad_arg; - if (text.size % (size_t)cipher_len != 0) - goto bad_arg; - - if (ivec_size == 0) { - if (argc != 4) - goto bad_arg; - } else { - if (argc != 5) - goto bad_arg; - if (!enif_inspect_iolist_as_binary(env, argv[2], &ivec)) - goto bad_arg; - if (ivec.size != (size_t)ivec_size) - goto bad_arg; - } - - if ((out = enif_make_new_binary(env, text.size, &ret)) == NULL) - goto err; - if ((ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - - if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, - (argv[argc - 1] == atom_true))) - goto err; - if (!EVP_CIPHER_CTX_set_key_length(ctx, (int)key.size)) - goto err; - - if (EVP_CIPHER_type(cipher) == NID_rc2_cbc) { - if (key.size > INT_MAX / 8) - goto err; - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, (int)key.size * 8, NULL)) - goto err; - } - - if (!EVP_CipherInit_ex(ctx, NULL, NULL, key.data, - ivec_size ? ivec.data : NULL, -1)) - goto err; - if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) - goto err; - - /* OpenSSL 0.9.8h asserts text.size > 0 */ - if (text.size > 0) { - if (!EVP_CipherUpdate(ctx, out, &out_size, text.data, (int)text.size)) - goto err; - if (ASSERT(out_size == text.size), 0) - goto err; - if (!EVP_CipherFinal_ex(ctx, out + out_size, &out_size)) - goto err; - } - - ASSERT(out_size == 0); - CONSUME_REDS(env, text); - goto done; - - bad_arg: - ret = enif_make_badarg(env); - goto done; - - err: - ret = enif_raise_exception(env, atom_notsup); - - done: - if (ctx) - EVP_CIPHER_CTX_free(ctx); - return ret; -} diff --git a/lib/crypto/c_src/block.h b/lib/crypto/c_src/block.h deleted file mode 100644 index cc5e78ce12..0000000000 --- a/lib/crypto/c_src/block.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#ifndef E_BLOCK_H__ -#define E_BLOCK_H__ 1 - -#include "common.h" - -ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); - -#endif /* E_BLOCK_H__ */ diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index c6a5dde67f..ac9823887a 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -29,7 +29,6 @@ #include "aes.h" #include "algorithms.h" #include "api_ng.h" -#include "block.h" #include "bn.h" #include "chacha20.h" #include "cipher.h" @@ -80,8 +79,6 @@ static ErlNifFunc nif_funcs[] = { {"hmac_final_nif", 2, hmac_final_nif, 0}, {"cmac_nif", 3, cmac_nif, 0}, {"cipher_info_nif", 1, cipher_info_nif, 0}, - {"block_crypt_nif", 5, block_crypt_nif, 0}, - {"block_crypt_nif", 4, block_crypt_nif, 0}, {"aes_ige_crypt_nif", 4, aes_ige_crypt_nif, 0}, {"aes_ctr_stream_init", 2, aes_ctr_stream_init, 0}, {"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt, 0}, -- cgit v1.2.3 From c209e1ecc6aac833b8a1d5da86d86ca04c7d7085 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 28 Feb 2019 20:00:12 +0100 Subject: crypto: Test the new api --- lib/crypto/test/crypto_SUITE.erl | 98 +++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 7257f4fb9f..d2eb6cbcb3 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -9,7 +9,7 @@ %% %% http://www.apache.org/licenses/LICENSE-2.0 %% -%% Unless required by applicable law or agreed to in writing, software + %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and @@ -166,31 +166,31 @@ groups() -> compute_bug]}, {ecdh, [], [use_all_elliptic_curves, compute, generate]}, {srp, [], [generate_compute]}, - {des_cbc, [], [block]}, - {des_cfb, [], [block]}, - {des3_cbc,[], [block]}, - {des_ede3,[], [block]}, - {des3_cbf,[], [block]}, - {des3_cfb,[], [block]}, - {rc2_cbc,[], [block]}, - {aes_cbc128,[], [block, cmac]}, - {aes_cfb8,[], [block]}, - {aes_cfb128,[], [block]}, - {aes_cbc256,[], [block, cmac]}, - {aes_ecb,[], [block]}, + {des_cbc, [], [block, api_ng]}, + {des_cfb, [], [block, api_ng]}, + {des3_cbc,[], [block, api_ng]}, + {des_ede3,[], [block, api_ng]}, + {des3_cbf,[], [block, api_ng]}, + {des3_cfb,[], [block, api_ng]}, + {rc2_cbc,[], [block, api_ng]}, + {aes_cbc128,[], [block, api_ng, cmac]}, + {aes_cfb8,[], [block, api_ng]}, + {aes_cfb128,[], [block, api_ng]}, + {aes_cbc256,[], [block, api_ng, cmac]}, + {aes_ecb,[], [block, api_ng]}, {aes_ige256,[], [block]}, - {blowfish_cbc, [], [block]}, - {blowfish_ecb, [], [block]}, - {blowfish_cfb64, [], [block]}, - {blowfish_ofb64,[], [block]}, - {rc4, [], [stream]}, - {aes_ctr, [], [stream]}, + {blowfish_cbc, [], [block, api_ng]}, + {blowfish_ecb, [], [block, api_ng]}, + {blowfish_cfb64, [], [block, api_ng]}, + {blowfish_ofb64,[], [block, api_ng]}, + {rc4, [], [stream, api_ng]}, + {aes_ctr, [], [stream, api_ng]}, {aes_ccm, [], [aead]}, {aes_gcm, [], [aead]}, {chacha20_poly1305, [], [aead]}, - {chacha20, [], [stream]}, + {chacha20, [], [stream, api_ng]}, {poly1305, [], [poly1305]}, - {aes_cbc, [], [block]}, + {aes_cbc, [], [block, api_ng]}, {no_aes_cfb8,[], [no_support, no_block]}, {no_aes_cfb128,[], [no_support, no_block]}, {no_md4, [], [no_support, no_hash]}, @@ -439,6 +439,61 @@ no_block(Config) when is_list(Config) -> notsup(fun crypto:block_encrypt/N, Args), notsup(fun crypto:block_decrypt/N, Args). %%-------------------------------------------------------------------- +api_ng() -> + [{doc, "Test new api"}]. + +api_ng(Config) when is_list(Config) -> + Fips = proplists:get_bool(fips, Config), + Type = ?config(type, Config), + Blocks = lazy_eval(proplists:get_value(block, Config, [])), + Streams = lazy_eval(proplists:get_value(stream, Config, [])), + lists:foreach(fun api_ng_cipher_increment/1, Blocks++Streams). + + +api_ng_cipher_increment({Type, Key, PlainTexts}=_X) -> + ct:log("~p",[_X]), + api_ng_cipher_increment({Type, Key, <<>>, PlainTexts}); + +api_ng_cipher_increment({Type, Key, IV, PlainTexts}=_X) -> + ct:log("~p",[_X]), + api_ng_cipher_increment({Type, Key, IV, PlainTexts, undefined}); + +api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> + ct:log("~p",[_X]), + PlainTexts = iolistify(PlainText0), + {ok,RefEnc} = crypto:crypto_init(Type, Key, IV, true), + {ok,RefDec} = crypto:crypto_init(Type, Key, IV, false), + EncTexts = api_ng_cipher_increment_loop(RefEnc, PlainTexts), + Enc = iolist_to_binary(EncTexts), + case ExpectedEncText of + undefined -> + ok; + Enc -> + ok; + OtherEnc -> + ct:fail({{crypto, api_ng_encrypt, [IV,EncTexts]}, {expected, ExpectedEncText}, {got, OtherEnc}}) + end, + Plain = iolist_to_binary(PlainTexts), + case iolist_to_binary(api_ng_cipher_increment_loop(RefDec, EncTexts)) of + Plain -> + ok; + OtherPT -> + ct:fail({{crypto, api_ng_decrypt, [IV,EncTexts]}, {expected, Plain}, {got, OtherPT}}) + end. + + +api_ng_cipher_increment_loop(Ref, InTexts) -> + lists:map(fun(Txt) -> + case crypto:crypto_update(Ref, Txt) of + Bin when is_binary(Bin) -> + Bin; + {error,Error} -> + ct:pal("Txt = ~p",[Txt]), + ct:fail("~p",[Error]) + end + end, InTexts). + +%%-------------------------------------------------------------------- no_aead() -> [{doc, "Test disabled aead ciphers"}]. no_aead(Config) when is_list(Config) -> @@ -774,6 +829,7 @@ cmac_check({Type, Key, Text, Size, CMac}) -> ct:fail({{crypto, cmac, [Type, Key, Text, Size]}, {expected, ExpCMac}, {got, Other}}) end. + block_cipher({Type, Key, PlainText}) -> Plain = iolist_to_binary(PlainText), CipherText = crypto:block_encrypt(Type, Key, PlainText), -- cgit v1.2.3 From cd08c844693fbb26d545f9cd981bfa9ae2d08042 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 12:19:18 +0100 Subject: crypto: Use/implement new funcs for stream-api --- lib/crypto/c_src/api_ng.c | 54 ++++++--- lib/crypto/c_src/crypto.c | 11 -- lib/crypto/src/crypto.erl | 278 ++++++++++++++++++++-------------------------- 3 files changed, 158 insertions(+), 185 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 50c0e9fcf6..1a5867eaaf 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -159,12 +159,6 @@ static int get_init_args(ErlNifEnv* env, goto err; } - if (encflg == -1) - { - *return_term = atom_undefined; - goto err; // Yes... - } - /* Initialize the EVP_CIPHER_CTX */ ctx_res->ctx = EVP_CIPHER_CTX_new(); @@ -198,7 +192,7 @@ static int get_init_args(ErlNifEnv* env, } } - if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, encflg)) { + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, -1)) { *return_term = ERROR_Str(env, "Can't initialize key and/or iv"); goto err; } @@ -254,6 +248,7 @@ static int get_update_args(ErlNifEnv* env, if (enif_get_tuple(env, newstate_and_outdata, &tuple_argc, &tuple_argv) && (tuple_argc == 2)) { /* newstate_and_outdata = {NewState, OutData} */ ctx_res->state = enif_make_copy(ctx_res->env, tuple_argv[0]); + /* Return the OutData (from the newstate_and_outdata tuple) only: */ *return_term = tuple_argv[1]; } } @@ -281,6 +276,7 @@ static int get_update_args(ErlNifEnv* env, } CONSUME_REDS(env, in_data_bin); + /* return the result text as a binary: */ *return_term = enif_make_binary(env, &out_data_bin); } @@ -301,17 +297,43 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg struct evp_cipher_ctx *ctx_res = NULL; const struct cipher_type_t *cipherp; ERL_NIF_TERM ret; - - if ((ctx_res = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - return ERROR_Str(env, "Can't allocate resource"); - - if (!get_init_args(env, ctx_res, argv[0], argv[1], argv[2], argv[argc-1], - &cipherp, &ret)) - /* Error msg in &ret */ + int encflg; + + if (enif_is_atom(env, argv[0])) { + if ((ctx_res = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) + return ERROR_Str(env, "Can't allocate resource"); + + if (!get_init_args(env, ctx_res, argv[0], argv[1], argv[2], argv[argc-1], + &cipherp, &ret)) + /* Error msg in &ret */ + goto ret; + + ret = enif_make_resource(env, ctx_res); + if(ctx_res) enif_release_resource(ctx_res); + + } else if (enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res)) { + /* Fetch the flag telling if we are going to encrypt (=true) or decrypt (=false) */ + if (argv[3] == atom_true) + encflg = 1; + else if (argv[3] == atom_false) + encflg = 0; + else { + ret = ERROR_Str(env, "Bad enc flag"); + goto ret; + } + if (ctx_res->ctx) { + /* It is *not* a ctx_res for the compatibility handling of non-EVP aes_ctr */ + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, NULL, NULL, encflg)) { + ret = ERROR_Str(env, "Can't initialize encflag"); + goto ret; + } + } + ret = argv[0]; + } else { + ret = ERROR_Str(env, "Bad 1:st arg"); goto ret; + } - ret = enif_make_resource(env, ctx_res); - if(ctx_res) enif_release_resource(ctx_res); ret: return ret; } diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index ac9823887a..501c1ffb42 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -30,7 +30,6 @@ #include "algorithms.h" #include "api_ng.h" #include "bn.h" -#include "chacha20.h" #include "cipher.h" #include "cmac.h" #include "dh.h" @@ -49,7 +48,6 @@ #include "pkey.h" #include "poly1305.h" #include "rand.h" -#include "rc4.h" #include "rsa.h" #include "srp.h" @@ -80,9 +78,6 @@ static ErlNifFunc nif_funcs[] = { {"cmac_nif", 3, cmac_nif, 0}, {"cipher_info_nif", 1, cipher_info_nif, 0}, {"aes_ige_crypt_nif", 4, aes_ige_crypt_nif, 0}, - {"aes_ctr_stream_init", 2, aes_ctr_stream_init, 0}, - {"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt, 0}, - {"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt, 0}, {"ng_crypto_init_nif", 4, ng_crypto_init_nif, 0}, {"ng_crypto_update_nif", 2, ng_crypto_update_nif, 0}, {"ng_crypto_one_shot_nif", 5, ng_crypto_one_shot_nif, 0}, @@ -91,8 +86,6 @@ static ErlNifFunc nif_funcs[] = { {"rand_uniform_nif", 2, rand_uniform_nif, 0}, {"mod_exp_nif", 4, mod_exp_nif, 0}, {"do_exor", 2, do_exor, 0}, - {"rc4_set_key", 1, rc4_set_key, 0}, - {"rc4_encrypt_with_state", 2, rc4_encrypt_with_state, 0}, {"pkey_sign_nif", 5, pkey_sign_nif, 0}, {"pkey_verify_nif", 6, pkey_verify_nif, 0}, {"pkey_crypt_nif", 6, pkey_crypt_nif, 0}, @@ -114,10 +107,6 @@ static ErlNifFunc nif_funcs[] = { {"aead_encrypt", 6, aead_encrypt, 0}, {"aead_decrypt", 6, aead_decrypt, 0}, - {"chacha20_stream_init", 2, chacha20_stream_init, 0}, - {"chacha20_stream_encrypt", 2, chacha20_stream_crypt, 0}, - {"chacha20_stream_decrypt", 2, chacha20_stream_crypt, 0}, - {"poly1305_nif", 2, poly1305_nif, 0}, {"engine_by_id_nif", 1, engine_by_id_nif, 0}, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 96213fa6e6..608610f85e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -50,14 +50,9 @@ -export([rand_seed/1]). %% Experiment --export([crypto_init/4, +-export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, - crypto_one_shot/5, - - %% Emulates old api: - crypto_stream_init/2, crypto_stream_init/3, - crypto_stream_encrypt/2, - crypto_stream_decrypt/2 + crypto_one_shot/5 ]). @@ -633,9 +628,11 @@ next_iv(des_cfb, Data, IVec) -> next_iv(Type, Data, _Ivec) -> next_iv(Type, Data). -%%%---- Stream ciphers +%%%-------- Stream ciphers API --opaque stream_state() :: {stream_cipher(), reference()}. +-opaque stream_state() :: {stream_cipher(), + crypto_state() | {crypto_state(),flg_undefined} + }. -type stream_cipher() :: stream_cipher_iv() | stream_cipher_no_iv() . -type stream_cipher_no_iv() :: rc4 . @@ -645,47 +642,67 @@ next_iv(Type, Data, _Ivec) -> | aes_256_ctr | chacha20 . --spec stream_init(Type, Key, IVec) -> State when Type :: stream_cipher_iv(), - Key :: iodata(), - IVec :: binary(), - State :: stream_state() . -stream_init(aes_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_128_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_192_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_256_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(chacha20, Key, Ivec) -> - {chacha20, chacha20_stream_init(Key,Ivec)}. - --spec stream_init(Type, Key) -> State when Type :: stream_cipher_no_iv(), - Key :: iodata(), - State :: stream_state() . -stream_init(rc4, Key) -> - {rc4, notsup_to_error(rc4_set_key(Key))}. - --spec stream_encrypt(State, PlainText) -> {NewState, CipherText} +%%%---- stream_init +-spec stream_init(Type, Key, IVec) -> State | no_return() + when Type :: stream_cipher_iv(), + Key :: iodata(), + IVec :: binary(), + State :: stream_state() . +stream_init(Type, Key, IVec) when is_binary(IVec) -> + case crypto_init(Type, Key, IVec) of + {ok,Ref} -> + {Type, {Ref,flg_undefined}}; + {error,_} -> + error(badarg) + end. + + +-spec stream_init(Type, Key) -> State | no_return() + when Type :: stream_cipher_no_iv(), + Key :: iodata(), + State :: stream_state() . +stream_init(rc4 = Type, Key) -> + case crypto_init(Type, Key, undefined) of + {ok,Ref} -> + {Type, {Ref,flg_undefined}}; + {error,_} -> + error(badarg) + end. + +%%%---- stream_encrypt +-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return() when State :: stream_state(), PlainText :: iodata(), NewState :: stream_state(), CipherText :: iodata() . -stream_encrypt(State, Data0) -> - Data = iolist_to_binary(Data0), - MaxByts = max_bytes(), - stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). +stream_encrypt(State, Data) -> + crypto_stream_emulate(State, Data, true). --spec stream_decrypt(State, CipherText) -> {NewState, PlainText} +%%%---- stream_decrypt +-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return() when State :: stream_state(), CipherText :: iodata(), NewState :: stream_state(), PlainText :: iodata() . -stream_decrypt(State, Data0) -> - Data = iolist_to_binary(Data0), - MaxByts = max_bytes(), - stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). +stream_decrypt(State, Data) -> + crypto_stream_emulate(State, Data, false). + +%%%-------- helpers +crypto_stream_emulate({Cipher,{Ref,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref) -> + case crypto_init(Ref, EncryptFlag) of + {error,_} -> + error(badarg); + MaybeNewRef when is_reference(MaybeNewRef) -> + crypto_stream_emulate({Cipher,MaybeNewRef}, Data, EncryptFlag) + end; +crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> + case crypto_update(Ref, Data) of + {error,_} -> + error(badarg); + Bin when is_binary(Bin) -> + {{Cipher,Ref},Bin} + end. %%%================================================================ %%% @@ -1789,59 +1806,7 @@ aead_decrypt(_Type, _Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub. aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. - -%% Stream ciphers -------------------------------------------------------------------- - -stream_crypt(Fun, State, Data, Size, MaxByts, []) when Size =< MaxByts -> - Fun(State, Data); -stream_crypt(Fun, State0, Data, Size, MaxByts, Acc) when Size =< MaxByts -> - {State, Cipher} = Fun(State0, Data), - {State, list_to_binary(lists:reverse([Cipher | Acc]))}; -stream_crypt(Fun, State0, Data, _, MaxByts, Acc) -> - <> = Data, - {State, CipherText} = Fun(State0, Increment), - stream_crypt(Fun, State, Rest, erlang:byte_size(Rest), MaxByts, [CipherText | Acc]). - -do_stream_encrypt({aes_ctr, State0}, Data) -> - {State, Cipher} = aes_ctr_stream_encrypt(State0, Data), - {{aes_ctr, State}, Cipher}; -do_stream_encrypt({rc4, State0}, Data) -> - {State, Cipher} = rc4_encrypt_with_state(State0, Data), - {{rc4, State}, Cipher}; -do_stream_encrypt({chacha20, State0}, Data) -> - {State, Cipher} = chacha20_stream_encrypt(State0, Data), - {{chacha20, State}, Cipher}. - -do_stream_decrypt({aes_ctr, State0}, Data) -> - {State, Text} = aes_ctr_stream_decrypt(State0, Data), - {{aes_ctr, State}, Text}; -do_stream_decrypt({rc4, State0}, Data) -> - {State, Text} = rc4_encrypt_with_state(State0, Data), - {{rc4, State}, Text}; -do_stream_decrypt({chacha20, State0}, Data) -> - {State, Cipher} = chacha20_stream_decrypt(State0, Data), - {{chacha20, State}, Cipher}. - - -%% -%% AES - in counter mode (CTR) with state maintained for multi-call streaming -%% -aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub. -aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub. -aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub. - -%% -%% RC4 - symmetric stream cipher -%% -rc4_set_key(_Key) -> ?nif_stub. -rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. - -%% -%% CHACHA20 - stream cipher -%% -chacha20_stream_init(_Key, _IVec) -> ?nif_stub. -chacha20_stream_encrypt(_State, _Data) -> ?nif_stub. -chacha20_stream_decrypt(_State, _Data) -> ?nif_stub. +%%%================================================================ %% Secure remote password ------------------------------------------------------------------- @@ -2214,7 +2179,7 @@ check_otp_test_engine(LibDir) -> %%% -> {ok,State::ref()} | {error,Reason} --opaque crypto_state() :: reference() | {any(),any(),any(),any()}. +-opaque crypto_state() :: reference() . %%%---------------------------------------------------------------- @@ -2222,32 +2187,64 @@ check_otp_test_engine(LibDir) -> %%% Create and initialize a new state for encryption or decryption %%% --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} | undefined +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} when Cipher :: stream_cipher() | block_cipher_with_iv() - | block_cipher_without_iv() , + | block_cipher_without_iv(), Key :: iodata(), - IV :: iodata(), - EncryptFlag :: boolean() | undefined, + IV :: iodata() | undefined, + EncryptFlag :: boolean(), State :: crypto_state() . +crypto_init(Cipher, Key, undefined, EncryptFlag) -> + crypto_init(Cipher, Key, <<>>, EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), + case ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag) of - {error,Error} -> - {error,Error}; - undefined -> % For compatibility function crypto_stream_init/3 - undefined; Ref when is_reference(Ref) -> {ok,Ref}; - State when is_tuple(State), - size(State)==4 -> - {ok,State} % compatibility with old cryptolibs < 1.0.1 + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + State :: crypto_state() . +crypto_init(Cipher, Key, undefined) -> + crypto_init(Cipher, Key, <<>>); + +crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + undefined) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} end. +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + when Ref :: crypto_state(), + EncryptFlag :: boolean() . + +crypto_init(Ref, EncryptFlag) when is_reference(Ref), + is_atom(EncryptFlag) -> + case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of + {error,Error} -> + {error,Error}; + R when is_reference(R) -> + R + end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt a sequence of bytes. The sum of the sizes @@ -2255,10 +2252,10 @@ crypto_init(Cipher, Key, IV, EncryptFlag) -> %%% blocksize. %%% --spec crypto_update(State, Data) -> {ok,Result} | {error,term()} +-spec crypto_update(State, Data) -> Result | {error,term()} when State :: crypto_state(), Data :: iodata(), - Result :: binary() | {crypto_state(),binary()}. + Result :: binary() . crypto_update(State, Data0) -> case iolist_to_binary(Data0) of <<>> -> @@ -2267,19 +2264,12 @@ crypto_update(State, Data0) -> ng_crypto_update_nif(State, Data) end. -%%%---------------------------------------------------------------- -%%% NIFs - -ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. - -%% _Data MUST be binary() -ng_crypto_update_nif(_State, _Data) -> ?nif_stub. - -%% _Data MUST be binary() -ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. -%%%================================================================ -%%% Compatibility functions to be called by "old" api functions. +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt one set bytes. +%%% The size must be an integer multiple of the crypto's blocksize. +%%% crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> case iolist_to_binary(Data0) of @@ -2289,51 +2279,23 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) end. -%%%-------------------------------- -%%%---- stream init, encrypt/decrypt - -crypto_stream_init(Cipher, Key) -> - crypto_stream_init(Cipher, Key, <<>>). - -crypto_stream_init(Cipher, Key0, IV0) -> - Key = iolist_to_binary(Key0), - IV = iolist_to_binary(IV0), - %% First check the argumensts: - case crypto_init(Cipher, Key, IV, undefined) of - undefined -> - {Cipher, {Key, IV}}; - {error,_} -> - {error,badarg} - end. - -crypto_stream_encrypt(State, PlainText) -> - crypto_stream_emulate(State, PlainText, true). - -crypto_stream_decrypt(State, CryptoText) -> - crypto_stream_emulate(State, CryptoText, false). +%%%---------------------------------------------------------------- +%%% NIFs +ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -%%%---- helper -crypto_stream_emulate({Cipher,{Key,IV}}, Data, EncryptFlag) -> - case crypto_init(Cipher, Key, IV, EncryptFlag) of - {ok,State} -> - crypto_stream_emulate({Cipher,State}, Data, EncryptFlag); - {error,_} -> - error(badarg) - end; -crypto_stream_emulate({Cipher,State}, Data, _) -> - case crypto_update(State, Data) of - {ok, {State1,Bin}} when is_binary(Bin) -> {{Cipher,State1},Bin}; - {ok,Bin} when is_binary(Bin) -> {{Cipher,State},Bin}; - {error,_} -> error(badarg) - end. +%% _Data MUST be binary() +ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -%%%================================================================ +%% _Data MUST be binary() +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. +%%%---------------------------------------------------------------- +%%% Cipher aliases +%%% prepend_cipher_aliases(L) -> [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. - %%%---- des_ede3_cbc alias(des3_cbc) -> des_ede3_cbc; alias(des_ede3) -> des_ede3_cbc; -- cgit v1.2.3 From bcf301f917fdcf29583421c5cb4e1c3f37653319 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 12:13:50 +0100 Subject: crypto: Remove chacha20.c,h and rc4.c,h Replaced by api_ng.c --- lib/crypto/c_src/Makefile.in | 2 - lib/crypto/c_src/chacha20.c | 124 ------------------------------------------- lib/crypto/c_src/chacha20.h | 29 ---------- lib/crypto/c_src/rc4.c | 92 -------------------------------- lib/crypto/c_src/rc4.h | 29 ---------- 5 files changed, 276 deletions(-) delete mode 100644 lib/crypto/c_src/chacha20.c delete mode 100644 lib/crypto/c_src/chacha20.h delete mode 100644 lib/crypto/c_src/rc4.c delete mode 100644 lib/crypto/c_src/rc4.h (limited to 'lib') diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 89de220e7b..b6a65d7488 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -78,7 +78,6 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \ $(OBJDIR)/api_ng$(TYPEMARKER).o \ $(OBJDIR)/atoms$(TYPEMARKER).o \ $(OBJDIR)/bn$(TYPEMARKER).o \ - $(OBJDIR)/chacha20$(TYPEMARKER).o \ $(OBJDIR)/cipher$(TYPEMARKER).o \ $(OBJDIR)/cmac$(TYPEMARKER).o \ $(OBJDIR)/dh$(TYPEMARKER).o \ @@ -97,7 +96,6 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \ $(OBJDIR)/pkey$(TYPEMARKER).o \ $(OBJDIR)/poly1305$(TYPEMARKER).o \ $(OBJDIR)/rand$(TYPEMARKER).o \ - $(OBJDIR)/rc4$(TYPEMARKER).o \ $(OBJDIR)/rsa$(TYPEMARKER).o \ $(OBJDIR)/srp$(TYPEMARKER).o CALLBACK_OBJS = $(OBJDIR)/crypto_callback$(TYPEMARKER).o diff --git a/lib/crypto/c_src/chacha20.c b/lib/crypto/c_src/chacha20.c deleted file mode 100644 index cfcc395dca..0000000000 --- a/lib/crypto/c_src/chacha20.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#include "chacha20.h" -#include "cipher.h" - -ERL_NIF_TERM chacha20_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Key, IV) */ -#if defined(HAVE_CHACHA20) - ErlNifBinary key_bin, ivec_bin; - struct evp_cipher_ctx *ctx = NULL; - const EVP_CIPHER *cipher; - ERL_NIF_TERM ret; - - ASSERT(argc == 2); - - if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)) - goto bad_arg; - if (key_bin.size != 32) - goto bad_arg; - if (!enif_inspect_binary(env, argv[1], &ivec_bin)) - goto bad_arg; - if (ivec_bin.size != 16) - goto bad_arg; - - cipher = EVP_chacha20(); - - if ((ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - goto err; - if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - - if (EVP_CipherInit_ex(ctx->ctx, cipher, NULL, - key_bin.data, ivec_bin.data, 1) != 1) - goto err; - if (EVP_CIPHER_CTX_set_padding(ctx->ctx, 0) != 1) - goto err; - - ret = enif_make_resource(env, ctx); - goto done; - - bad_arg: - return enif_make_badarg(env); - - err: - ret = enif_make_badarg(env); - - done: - if (ctx) - enif_release_resource(ctx); - return ret; - -#else - return enif_raise_exception(env, atom_notsup); -#endif -} - -ERL_NIF_TERM chacha20_stream_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (State, Data) */ -#if defined(HAVE_CHACHA20) - struct evp_cipher_ctx *ctx = NULL, *new_ctx = NULL; - ErlNifBinary data_bin; - ERL_NIF_TERM ret, cipher_term; - unsigned char *out; - int outl = 0; - - ASSERT(argc == 2); - - if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx)) - goto bad_arg; - if (!enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) - goto bad_arg; - if (data_bin.size > INT_MAX) - goto bad_arg; - - if ((new_ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - goto err; - if ((new_ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - - if (EVP_CIPHER_CTX_copy(new_ctx->ctx, ctx->ctx) != 1) - goto err; - if ((out = enif_make_new_binary(env, data_bin.size, &cipher_term)) == NULL) - goto err; - if (EVP_CipherUpdate(new_ctx->ctx, out, &outl, data_bin.data, (int)data_bin.size) != 1) - goto err; - ASSERT(outl >= 0 && (size_t)outl == data_bin.size); - - ret = enif_make_tuple2(env, enif_make_resource(env, new_ctx), cipher_term); - CONSUME_REDS(env, data_bin); - goto done; - - bad_arg: - return enif_make_badarg(env); - - err: - ret = enif_make_badarg(env); - - done: - if (new_ctx) - enif_release_resource(new_ctx); - return ret; - -#else - return enif_raise_exception(env, atom_notsup); -#endif -} diff --git a/lib/crypto/c_src/chacha20.h b/lib/crypto/c_src/chacha20.h deleted file mode 100644 index 7e2ccae2bb..0000000000 --- a/lib/crypto/c_src/chacha20.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#ifndef E_CHACHA20_H__ -#define E_CHACHA20_H__ 1 - -#include "common.h" - -ERL_NIF_TERM chacha20_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -ERL_NIF_TERM chacha20_stream_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); - -#endif /* E_CHACHA20_H__ */ diff --git a/lib/crypto/c_src/rc4.c b/lib/crypto/c_src/rc4.c deleted file mode 100644 index e423661097..0000000000 --- a/lib/crypto/c_src/rc4.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#include "rc4.h" - -ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Key) */ -#ifndef OPENSSL_NO_RC4 - ErlNifBinary key; - ERL_NIF_TERM ret; - RC4_KEY *rc4_key; - - CHECK_NO_FIPS_MODE(); - - ASSERT(argc == 1); - - if (!enif_inspect_iolist_as_binary(env, argv[0], &key)) - goto bad_arg; - if (key.size > INT_MAX) - goto bad_arg; - - if ((rc4_key = (RC4_KEY*)enif_make_new_binary(env, sizeof(RC4_KEY), &ret)) == NULL) - goto err; - - RC4_set_key(rc4_key, (int)key.size, key.data); - return ret; - - bad_arg: - err: - return enif_make_badarg(env); - -#else - return enif_raise_exception(env, atom_notsup); -#endif -} - -ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (State, Data) */ -#ifndef OPENSSL_NO_RC4 - ErlNifBinary state, data; - RC4_KEY* rc4_key; - ERL_NIF_TERM new_state, new_data; - unsigned char *outp; - - CHECK_NO_FIPS_MODE(); - - ASSERT(argc == 2); - - if (!enif_inspect_iolist_as_binary(env, argv[0], &state)) - goto bad_arg; - if (state.size != sizeof(RC4_KEY)) - goto bad_arg; - if (!enif_inspect_iolist_as_binary(env, argv[1], &data)) - goto bad_arg; - - if ((rc4_key = (RC4_KEY*)enif_make_new_binary(env, sizeof(RC4_KEY), &new_state)) == NULL) - goto err; - if ((outp = enif_make_new_binary(env, data.size, &new_data)) == NULL) - goto err; - - memcpy(rc4_key, state.data, sizeof(RC4_KEY)); - RC4(rc4_key, data.size, data.data, outp); - - CONSUME_REDS(env, data); - return enif_make_tuple2(env, new_state, new_data); - - bad_arg: - err: - return enif_make_badarg(env); - -#else - return enif_raise_exception(env, atom_notsup); -#endif -} - diff --git a/lib/crypto/c_src/rc4.h b/lib/crypto/c_src/rc4.h deleted file mode 100644 index 28bf674253..0000000000 --- a/lib/crypto/c_src/rc4.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2010-2018. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - */ - -#ifndef E_RC4_H__ -#define E_RC4_H__ 1 - -#include "common.h" - -ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); - -#endif /* E_RC4_H__ */ -- cgit v1.2.3 From 2ec7cacec1c098f8c2ce28929634a0f564aa0431 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 12:16:14 +0100 Subject: crypto: Shrink aes.c,h (remove aes_ctr_stream_* funcs) --- lib/crypto/c_src/aes.c | 151 +------------------------------------------------ lib/crypto/c_src/aes.h | 3 - 2 files changed, 1 insertion(+), 153 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/aes.c b/lib/crypto/c_src/aes.c index ee2bb70fb7..4b01e629f9 100644 --- a/lib/crypto/c_src/aes.c +++ b/lib/crypto/c_src/aes.c @@ -166,156 +166,7 @@ ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv } -#ifdef HAVE_EVP_AES_CTR -ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Key, IVec) */ - ErlNifBinary key_bin, ivec_bin; - struct evp_cipher_ctx *ctx = NULL; - const EVP_CIPHER *cipher; - ERL_NIF_TERM ret; - - ASSERT(argc == 2); - - if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)) - goto bad_arg; - if (!enif_inspect_binary(env, argv[1], &ivec_bin)) - goto bad_arg; - if (ivec_bin.size != 16) - goto bad_arg; - - switch (key_bin.size) - { - case 16: - cipher = EVP_aes_128_ctr(); - break; - case 24: - cipher = EVP_aes_192_ctr(); - break; - case 32: - cipher = EVP_aes_256_ctr(); - break; - default: - goto bad_arg; - } - - if ((ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - goto err; - if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - - if (EVP_CipherInit_ex(ctx->ctx, cipher, NULL, - key_bin.data, ivec_bin.data, 1) != 1) - goto err; - - if (EVP_CIPHER_CTX_set_padding(ctx->ctx, 0) != 1) - goto err; - - ret = enif_make_resource(env, ctx); - goto done; - - bad_arg: - return enif_make_badarg(env); - - err: - ret = enif_make_badarg(env); - - done: - if (ctx) - enif_release_resource(ctx); - return ret; -} - -ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Context, Data) */ - struct evp_cipher_ctx *ctx = NULL, *new_ctx = NULL; - ErlNifBinary data_bin; - ERL_NIF_TERM ret, cipher_term; - unsigned char *out; - int outl = 0; - - ASSERT(argc == 2); - - if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx)) - goto bad_arg; - if (!enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) - goto bad_arg; - if (data_bin.size > INT_MAX) - goto bad_arg; - - if ((new_ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - goto err; - if ((new_ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - - if (EVP_CIPHER_CTX_copy(new_ctx->ctx, ctx->ctx) != 1) - goto err; - - if ((out = enif_make_new_binary(env, data_bin.size, &cipher_term)) == NULL) - goto err; - - if (EVP_CipherUpdate(new_ctx->ctx, out, &outl, data_bin.data, (int)data_bin.size) != 1) - goto err; - ASSERT(outl >= 0 && (size_t)outl == data_bin.size); - - ret = enif_make_tuple2(env, enif_make_resource(env, new_ctx), cipher_term); - CONSUME_REDS(env,data_bin); - goto done; - - bad_arg: - return enif_make_badarg(env); - - err: - ret = enif_make_badarg(env); - - done: - if (new_ctx) - enif_release_resource(new_ctx); - return ret; -} - -#else /* if not HAVE_EVP_AES_CTR */ - -ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Key, IVec) */ - ASSERT(argc == 2); - - return aes_ctr_stream_init_compat(env, argv[0], argv[1]); -} - - -ERL_NIF_TERM aes_ctr_stream_init_compat(ErlNifEnv* env, const ERL_NIF_TERM key_term, const ERL_NIF_TERM iv_term) -{ - ErlNifBinary key_bin, ivec_bin; - ERL_NIF_TERM ecount_bin; - unsigned char *outp; - - if (!enif_inspect_iolist_as_binary(env, key_term, &key_bin)) - goto bad_arg; - if (key_bin.size != 16 && key_bin.size != 24 && key_bin.size != 32) - goto bad_arg; - if (!enif_inspect_binary(env, iv_term, &ivec_bin)) - goto bad_arg; - if (ivec_bin.size != 16) - goto bad_arg; - if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) - goto err; - memset(outp, 0, AES_BLOCK_SIZE); - - return enif_make_tuple4(env, key_term, iv_term, ecount_bin, enif_make_int(env, 0)); - - bad_arg: - err: - return enif_make_badarg(env); -} - -ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - ASSERT(argc == 2); - - return aes_ctr_stream_encrypt_compat(env, argv[0], argv[1]); -} - - +#if !defined(HAVE_EVP_AES_CTR) ERL_NIF_TERM aes_ctr_stream_encrypt_compat(ErlNifEnv* env, const ERL_NIF_TERM state_arg, const ERL_NIF_TERM data_arg) {/* ({Key, IVec, ECount, Num}, Data) */ ErlNifBinary key_bin, ivec_bin, text_bin, ecount_bin; diff --git a/lib/crypto/c_src/aes.h b/lib/crypto/c_src/aes.h index 527d041410..c0b2b91f8d 100644 --- a/lib/crypto/c_src/aes.h +++ b/lib/crypto/c_src/aes.h @@ -27,10 +27,7 @@ ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] ERL_NIF_TERM aes_cfb_128_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); #if !defined(HAVE_EVP_AES_CTR) -ERL_NIF_TERM aes_ctr_stream_init_compat(ErlNifEnv* env, const ERL_NIF_TERM key_term, const ERL_NIF_TERM iv_term); ERL_NIF_TERM aes_ctr_stream_encrypt_compat(ErlNifEnv* env, const ERL_NIF_TERM state_arg, const ERL_NIF_TERM data_arg); #endif -- cgit v1.2.3 From e037832aedd190c62e3a965fb7bdd44c160a86dc Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 5 Mar 2019 16:11:23 +0100 Subject: crypto: Test fixes for stream api emulated by the new api The test case for the stream api creates one initial state with stream_init/3 That initial state is then used for a series of encrypts, and for a series of decrypts. That is not possible any more since the changes are saved in the nif reference. --- lib/crypto/test/crypto_SUITE.erl | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index d2eb6cbcb3..241c5172c4 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -907,46 +907,51 @@ block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, Ciph stream_cipher({Type, Key, PlainText}) -> Plain = iolist_to_binary(PlainText), - State = crypto:stream_init(Type, Key), - {_, CipherText} = crypto:stream_encrypt(State, PlainText), - case crypto:stream_decrypt(State, CipherText) of + StateE = crypto:stream_init(Type, Key), + StateD = crypto:stream_init(Type, Key), + {_, CipherText} = crypto:stream_encrypt(StateE, PlainText), + case crypto:stream_decrypt(StateD, CipherText) of {_, Plain} -> ok; Other -> - ct:fail({{crypto, stream_decrypt, [State, CipherText]}, {expected, PlainText}, {got, Other}}) + ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}}) end; stream_cipher({Type, Key, IV, PlainText}) -> Plain = iolist_to_binary(PlainText), - State = crypto:stream_init(Type, Key, IV), - {_, CipherText} = crypto:stream_encrypt(State, PlainText), - case crypto:stream_decrypt(State, CipherText) of + StateE = crypto:stream_init(Type, Key, IV), + StateD = crypto:stream_init(Type, Key, IV), + {_, CipherText} = crypto:stream_encrypt(StateE, PlainText), + case crypto:stream_decrypt(StateD, CipherText) of {_, Plain} -> ok; Other -> - ct:fail({{crypto, stream_decrypt, [State, CipherText]}, {expected, PlainText}, {got, Other}}) + ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}}) end; stream_cipher({Type, Key, IV, PlainText, CipherText}) -> Plain = iolist_to_binary(PlainText), - State = crypto:stream_init(Type, Key, IV), - case crypto:stream_encrypt(State, PlainText) of + StateE = crypto:stream_init(Type, Key, IV), + StateD = crypto:stream_init(Type, Key, IV), + case crypto:stream_encrypt(StateE, PlainText) of {_, CipherText} -> ok; {_, Other0} -> - ct:fail({{crypto, stream_encrypt, [State, Type, Key, IV, Plain]}, {expected, CipherText}, {got, Other0}}) + ct:fail({{crypto, stream_encrypt, [StateE, Type, Key, IV, Plain]}, {expected, CipherText}, {got, Other0}}) end, - case crypto:stream_decrypt(State, CipherText) of + case crypto:stream_decrypt(StateD, CipherText) of {_, Plain} -> ok; Other1 -> - ct:fail({{crypto, stream_decrypt, [State, CipherText]}, {expected, PlainText}, {got, Other1}}) + ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other1}}) end. stream_cipher_incment({Type, Key, PlainTexts}) -> - State = crypto:stream_init(Type, Key), - stream_cipher_incment_loop(State, State, PlainTexts, [], iolist_to_binary(PlainTexts)); + StateE = crypto:stream_init(Type, Key), + StateD = crypto:stream_init(Type, Key), + stream_cipher_incment_loop(StateE, StateD, PlainTexts, [], iolist_to_binary(PlainTexts)); stream_cipher_incment({Type, Key, IV, PlainTexts}) -> - State = crypto:stream_init(Type, Key, IV), - stream_cipher_incment_loop(State, State, PlainTexts, [], iolist_to_binary(PlainTexts)); + StateE = crypto:stream_init(Type, Key, IV), + StateD = crypto:stream_init(Type, Key, IV), + stream_cipher_incment_loop(StateE, StateD, PlainTexts, [], iolist_to_binary(PlainTexts)); stream_cipher_incment({Type, Key, IV, PlainTexts, _CipherText}) -> stream_cipher_incment({Type, Key, IV, PlainTexts}). -- cgit v1.2.3 From 2e1005c7961a5de0c02ebeb8e98720472cfb53d4 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 12:28:59 +0100 Subject: crypto: Remove unused variables in test case --- lib/crypto/test/crypto_SUITE.erl | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 241c5172c4..14e2c4a7a7 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -415,8 +415,6 @@ poly1305(Config) -> block() -> [{doc, "Test block ciphers"}]. block(Config) when is_list(Config) -> - Fips = proplists:get_bool(fips, Config), - Type = ?config(type, Config), Blocks = lazy_eval(proplists:get_value(block, Config)), lists:foreach(fun block_cipher/1, Blocks), lists:foreach(fun block_cipher/1, block_iolistify(Blocks)), @@ -443,8 +441,6 @@ api_ng() -> [{doc, "Test new api"}]. api_ng(Config) when is_list(Config) -> - Fips = proplists:get_bool(fips, Config), - Type = ?config(type, Config), Blocks = lazy_eval(proplists:get_value(block, Config, [])), Streams = lazy_eval(proplists:get_value(stream, Config, [])), lists:foreach(fun api_ng_cipher_increment/1, Blocks++Streams). -- cgit v1.2.3 From 4d436bfc6dacd45b501b92845f8cf3ef5c1308d9 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 14:39:21 +0100 Subject: crypto: Cleaning of comments + spec fixing --- lib/crypto/c_src/api_ng.c | 2 - lib/crypto/src/crypto.erl | 101 ++++++++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 42 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 1a5867eaaf..a91951c84e 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -25,8 +25,6 @@ /* * A unified set of functions for encryption/decryption. * - * EXPERIMENTAL!! - * */ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 608610f85e..68cc1c1f65 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -40,16 +40,22 @@ -export([rand_plugin_uniform/2]). -export([rand_cache_plugin_next/1]). -export([rand_uniform/2]). --export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]). -export([next_iv/2, next_iv/3]). --export([stream_init/2, stream_init/3, stream_encrypt/2, stream_decrypt/2]). -export([public_encrypt/4, private_decrypt/4]). -export([private_encrypt/4, public_decrypt/4]). -export([privkey_to_pubkey/2]). -export([ec_curve/1, ec_curves/0]). -export([rand_seed/1]). -%% Experiment +%% Old interface. Now implemented with the New interface +-export([stream_init/2, stream_init/3, + stream_encrypt/2, + stream_decrypt/2, + block_encrypt/3, block_encrypt/4, + block_decrypt/3, block_decrypt/4 + ]). + +%% New interface -export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, crypto_one_shot/5 @@ -528,7 +534,7 @@ poly1305(Key, Data) -> %%%================================================================ %%% -%%% Encrypt/decrypt +%%% Encrypt/decrypt, The "Old API" %%% %%%================================================================ @@ -601,33 +607,6 @@ do_block_decrypt(Type, Key, Ivec, Data) -> block_decrypt(Type, Key, Data) -> crypto_one_shot(Type, Key, <<>>, Data, false). -%%%---------------------------------------------------------------- --spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, - Data :: iodata(), - NextIVec :: binary(). -next_iv(Type, Data) when is_binary(Data) -> - IVecSize = case Type of - des_cbc -> 8; - des3_cbc -> 8; - aes_cbc -> 16; - aes_ige -> 32 - end, - {_, IVec} = split_binary(Data, size(Data) - IVecSize), - IVec; -next_iv(Type, Data) when is_list(Data) -> - next_iv(Type, list_to_binary(Data)). - --spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), - IVec :: binary(), - NextIVec :: binary(). - -next_iv(des_cfb, Data, IVec) -> - IVecAndData = list_to_binary([IVec, Data]), - {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8), - NewIVec; -next_iv(Type, Data, _Ivec) -> - next_iv(Type, Data). - %%%-------- Stream ciphers API -opaque stream_state() :: {stream_cipher(), @@ -704,6 +683,33 @@ crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> {{Cipher,Ref},Bin} end. +%%%---------------------------------------------------------------- +-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, + Data :: iodata(), + NextIVec :: binary(). +next_iv(Type, Data) when is_binary(Data) -> + IVecSize = case Type of + des_cbc -> 8; + des3_cbc -> 8; + aes_cbc -> 16; + aes_ige -> 32 + end, + {_, IVec} = split_binary(Data, size(Data) - IVecSize), + IVec; +next_iv(Type, Data) when is_list(Data) -> + next_iv(Type, list_to_binary(Data)). + +-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), + IVec :: binary(), + NextIVec :: binary(). + +next_iv(des_cfb, Data, IVec) -> + IVecAndData = list_to_binary([IVec, Data]), + {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8), + NewIVec; +next_iv(Type, Data, _Ivec) -> + next_iv(Type, Data). + %%%================================================================ %%% %%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib @@ -2172,12 +2178,11 @@ check_otp_test_engine(LibDir) -> end. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%================================================================ %%% -%%% Experimental NG +%%% Encrypt/decrypt, The "New API" %%% - -%%% -> {ok,State::ref()} | {error,Reason} +%%%================================================================ -opaque crypto_state() :: reference() . @@ -2233,11 +2238,11 @@ crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> -spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} - when Ref :: crypto_state(), - EncryptFlag :: boolean() . + when Ref :: crypto_state(), + EncryptFlag :: boolean() . crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> + is_atom(EncryptFlag) -> case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of {error,Error} -> {error,Error}; @@ -2271,6 +2276,18 @@ crypto_update(State, Data0) -> %%% The size must be an integer multiple of the crypto's blocksize. %%% +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + Data :: iodata(), + EncryptFlag :: boolean(), + Result :: binary() . +crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> + crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); + crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> case iolist_to_binary(Data0) of <<>> -> @@ -2282,12 +2299,16 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> %%%---------------------------------------------------------------- %%% NIFs +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -%% _Data MUST be binary() + +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -%% _Data MUST be binary() + +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%---------------------------------------------------------------- -- cgit v1.2.3 From 3a74629664f3d7f6ae7483954130dca7f9794c10 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 14:41:21 +0100 Subject: crypto: Relocate the new api code inside the crypto.erl file --- lib/crypto/src/crypto.erl | 303 +++++++++++++++++++++++----------------------- 1 file changed, 152 insertions(+), 151 deletions(-) (limited to 'lib') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 68cc1c1f65..b4e2582fc6 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -710,6 +710,158 @@ next_iv(des_cfb, Data, IVec) -> next_iv(Type, Data, _Ivec) -> next_iv(Type, Data). +%%%================================================================ +%%% +%%% Encrypt/decrypt, The "New API" +%%% +%%%================================================================ + +-opaque crypto_state() :: reference() . + + +%%%---------------------------------------------------------------- +%%% +%%% Create and initialize a new state for encryption or decryption +%%% + +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init(Cipher, Key, undefined, EncryptFlag) -> + crypto_init(Cipher, Key, <<>>, EncryptFlag); + +crypto_init(Cipher, Key, IV, EncryptFlag) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + EncryptFlag) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + State :: crypto_state() . +crypto_init(Cipher, Key, undefined) -> + crypto_init(Cipher, Key, <<>>); + +crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + undefined) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + when Ref :: crypto_state(), + EncryptFlag :: boolean() . + +crypto_init(Ref, EncryptFlag) when is_reference(Ref), + is_atom(EncryptFlag) -> + case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of + {error,Error} -> + {error,Error}; + R when is_reference(R) -> + R + end. + +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt a sequence of bytes. The sum of the sizes +%%% of all blocks must be an integer multiple of the crypto's +%%% blocksize. +%%% + +-spec crypto_update(State, Data) -> Result | {error,term()} + when State :: crypto_state(), + Data :: iodata(), + Result :: binary() . +crypto_update(State, Data0) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_update_nif(State, Data) + end. + + +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt one set bytes. +%%% The size must be an integer multiple of the crypto's blocksize. +%%% + +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + Data :: iodata(), + EncryptFlag :: boolean(), + Result :: binary() . +crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> + crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); + +crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) + end. + +%%%---------------------------------------------------------------- +%%% NIFs + +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . +ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. + + +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . +ng_crypto_update_nif(_State, _Data) -> ?nif_stub. + + +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. + +%%%---------------------------------------------------------------- +%%% Cipher aliases +%%% +prepend_cipher_aliases(L) -> + [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. + +%%%---- des_ede3_cbc +alias(des3_cbc) -> des_ede3_cbc; +alias(des_ede3) -> des_ede3_cbc; +%%%---- des_ede3_cfb +alias(des_ede3_cbf) -> des_ede3_cfb; +alias(des3_cbf) -> des_ede3_cfb; +alias(des3_cfb) -> des_ede3_cfb; +%%%---- aes_*_cbc +alias(aes_cbc128) -> aes_128_cbc; +alias(aes_cbc256) -> aes_256_cbc; + +alias(Alg) -> Alg. + %%%================================================================ %%% %%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib @@ -2178,154 +2330,3 @@ check_otp_test_engine(LibDir) -> end. -%%%================================================================ -%%% -%%% Encrypt/decrypt, The "New API" -%%% -%%%================================================================ - --opaque crypto_state() :: reference() . - - -%%%---------------------------------------------------------------- -%%% -%%% Create and initialize a new state for encryption or decryption -%%% - --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - EncryptFlag :: boolean(), - State :: crypto_state() . -crypto_init(Cipher, Key, undefined, EncryptFlag) -> - crypto_init(Cipher, Key, <<>>, EncryptFlag); - -crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - EncryptFlag) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. - - --spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - State :: crypto_state() . -crypto_init(Cipher, Key, undefined) -> - crypto_init(Cipher, Key, <<>>); - -crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - undefined) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. - - --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} - when Ref :: crypto_state(), - EncryptFlag :: boolean() . - -crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> - case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of - {error,Error} -> - {error,Error}; - R when is_reference(R) -> - R - end. - -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt a sequence of bytes. The sum of the sizes -%%% of all blocks must be an integer multiple of the crypto's -%%% blocksize. -%%% - --spec crypto_update(State, Data) -> Result | {error,term()} - when State :: crypto_state(), - Data :: iodata(), - Result :: binary() . -crypto_update(State, Data0) -> - case iolist_to_binary(Data0) of - <<>> -> - <<>>; % Known to fail on OpenSSL 0.9.8h - Data -> - ng_crypto_update_nif(State, Data) - end. - - -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt one set bytes. -%%% The size must be an integer multiple of the crypto's blocksize. -%%% - --spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - Data :: iodata(), - EncryptFlag :: boolean(), - Result :: binary() . -crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> - crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); - -crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> - case iolist_to_binary(Data0) of - <<>> -> - <<>>; % Known to fail on OpenSSL 0.9.8h - Data -> - ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) - end. - -%%%---------------------------------------------------------------- -%%% NIFs - --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} - ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . -ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. - - --spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . -ng_crypto_update_nif(_State, _Data) -> ?nif_stub. - - --spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. -ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. - -%%%---------------------------------------------------------------- -%%% Cipher aliases -%%% -prepend_cipher_aliases(L) -> - [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. - -%%%---- des_ede3_cbc -alias(des3_cbc) -> des_ede3_cbc; -alias(des_ede3) -> des_ede3_cbc; -%%%---- des_ede3_cfb -alias(des_ede3_cbf) -> des_ede3_cfb; -alias(des3_cbf) -> des_ede3_cfb; -alias(des3_cfb) -> des_ede3_cfb; -%%%---- aes_*_cbc -alias(aes_cbc128) -> aes_128_cbc; -alias(aes_cbc256) -> aes_256_cbc; - -alias(Alg) -> Alg. -- cgit v1.2.3 From 3f8f8054254cee6bf401e1e83662e05029bde750 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 8 Mar 2019 10:42:25 +0100 Subject: crypto: Exceptions as error return in api_ng --- lib/crypto/c_src/api_ng.c | 69 +++++++++++----------- lib/crypto/c_src/atoms.c | 2 + lib/crypto/c_src/atoms.h | 1 + lib/crypto/src/crypto.erl | 120 ++++++++++++++++----------------------- lib/crypto/test/crypto_SUITE.erl | 90 +++++++++++++++++++++-------- 5 files changed, 155 insertions(+), 127 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index a91951c84e..46522914b0 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -31,9 +31,14 @@ ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg -/* Try better error messages in new functions */ -#define ERROR_Term(Env, ReasonTerm) enif_make_tuple2((Env), atom_error, (ReasonTerm)) -#define ERROR_Str(Env, ReasonString) ERROR_Term((Env), enif_make_string((Env),(ReasonString),(ERL_NIF_LATIN1))) +/* All nif functions return a valid value or throws an exception */ +#define EXCP(Env, Class, Str) enif_raise_exception((Env), \ + enif_make_tuple2((Env), (Class), \ + enif_make_string((Env),(Str),(ERL_NIF_LATIN1)) )) + +#define EXCP_NOTSUP(Env, Str) EXCP((Env), atom_notsup, (Str)) +#define EXCP_BADARG(Env, Str) EXCP((Env), atom_badarg, (Str)) +#define EXCP_ERROR(Env, Str) EXCP((Env), atom_error, (Str)) #ifdef HAVE_ECB_IVEC_BUG @@ -73,33 +78,33 @@ static int get_init_args(ErlNifEnv* env, encflg = -1; else { - *return_term = ERROR_Str(env, "Bad enc flag"); + *return_term = EXCP_BADARG(env, "Bad enc flag"); goto err; } /* Fetch the key */ if (!enif_inspect_iolist_as_binary(env, key_arg, &key_bin)) { - *return_term = ERROR_Str(env, "Bad key"); + *return_term = EXCP_BADARG(env, "Bad key"); goto err; } /* Fetch cipher type */ if (!enif_is_atom(env, cipher_arg)) { - *return_term = ERROR_Str(env, "Cipher id is not an atom"); + *return_term = EXCP_BADARG(env, "Cipher id is not an atom"); goto err; } if (!(*cipherp = get_cipher_type(cipher_arg, key_bin.size))) { - *return_term = ERROR_Str(env, "Unknown cipher or bad key size for the cipher"); + *return_term = EXCP_BADARG(env, "Unknown cipher or bad key size for the cipher"); goto err; } if (FORBIDDEN_IN_FIPS(*cipherp)) { - *return_term = enif_raise_exception(env, atom_notsup); + *return_term = EXCP_NOTSUP(env, "Forbidden in FIPS"); goto err; } @@ -118,13 +123,13 @@ static int get_init_args(ErlNifEnv* env, if (ivec_len) { if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin)) { - *return_term = ERROR_Str(env, "Bad iv type"); + *return_term = EXCP_BADARG(env, "Bad iv type"); goto err; } if (ivec_len != ivec_bin.size) { - *return_term = ERROR_Str(env, "Bad iv size"); + *return_term = EXCP_BADARG(env, "Bad iv size"); goto err; } } @@ -137,14 +142,14 @@ static int get_init_args(ErlNifEnv* env, ERL_NIF_TERM ecount_bin; unsigned char *outp; if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) { - *return_term = ERROR_Str(env, "Can't allocate ecount_bin"); + *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin"); goto err; } memset(outp, 0, AES_BLOCK_SIZE); ctx_res->env = enif_alloc_env(); if (!ctx_res->env) { - *return_term = ERROR_Str(env, "Can't allocate env"); + *return_term = EXCP_ERROR(env, "Can't allocate env"); goto err; } ctx_res->state = @@ -153,7 +158,7 @@ static int get_init_args(ErlNifEnv* env, goto success; } #endif - *return_term = enif_raise_exception(env, atom_notsup); + *return_term = EXCP_NOTSUP(env, "Cipher"); goto err; } @@ -162,36 +167,36 @@ static int get_init_args(ErlNifEnv* env, ctx_res->ctx = EVP_CIPHER_CTX_new(); if (! ctx_res->ctx) { - *return_term = ERROR_Str(env, "Can't allocate context"); + *return_term = EXCP_ERROR(env, "Can't allocate context"); goto err; } if (!EVP_CipherInit_ex(ctx_res->ctx, (*cipherp)->cipher.p, NULL, NULL, NULL, encflg)) { - *return_term = ERROR_Str(env, "Can't initialize context, step 1"); + *return_term = EXCP_ERROR(env, "Can't initialize context, step 1"); goto err; } if (!EVP_CIPHER_CTX_set_key_length(ctx_res->ctx, (int)key_bin.size)) { - *return_term = ERROR_Str(env, "Can't initialize context, key_length"); + *return_term = EXCP_ERROR(env, "Can't initialize context, key_length"); goto err; } if (EVP_CIPHER_type((*cipherp)->cipher.p) == NID_rc2_cbc) { if (key_bin.size > INT_MAX / 8) { - *return_term = ERROR_Str(env, "To large rc2_cbc key"); + *return_term = EXCP_BADARG(env, "To large rc2_cbc key"); goto err; } if (!EVP_CIPHER_CTX_ctrl(ctx_res->ctx, EVP_CTRL_SET_RC2_KEY_BITS, (int)key_bin.size * 8, NULL)) { - *return_term = ERROR_Str(env, "ctrl rc2_cbc key"); + *return_term = EXCP_ERROR(env, "ctrl rc2_cbc key"); goto err; } } if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, -1)) { - *return_term = ERROR_Str(env, "Can't initialize key and/or iv"); + *return_term = EXCP_ERROR(env, "Can't initialize key and/or iv"); goto err; } @@ -223,7 +228,7 @@ static int get_update_args(ErlNifEnv* env, if (!enif_inspect_binary(env, indata_arg, &in_data_bin) ) { - *return_term = ERROR_Str(env, "Bad 2:nd arg"); + *return_term = EXCP_BADARG(env, "Bad 2:nd arg"); goto err; } @@ -257,19 +262,19 @@ static int get_update_args(ErlNifEnv* env, if (!enif_alloc_binary((size_t)in_data_bin.size+block_size, &out_data_bin)) { - *return_term = ERROR_Str(env, "Can't allocate outdata"); + *return_term = EXCP_ERROR(env, "Can't allocate outdata"); goto err; } if (!EVP_CipherUpdate(ctx_res->ctx, out_data_bin.data, &out_len, in_data_bin.data, in_data_bin.size)) { - *return_term = ERROR_Str(env, "Can't update"); + *return_term = EXCP_ERROR(env, "Can't update"); goto err; } if (!enif_realloc_binary(&out_data_bin, (size_t)out_len)) { - *return_term = ERROR_Str(env, "Can't reallocate"); + *return_term = EXCP_ERROR(env, "Can't reallocate"); goto err; } @@ -299,7 +304,7 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg if (enif_is_atom(env, argv[0])) { if ((ctx_res = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL) - return ERROR_Str(env, "Can't allocate resource"); + return EXCP_ERROR(env, "Can't allocate resource"); if (!get_init_args(env, ctx_res, argv[0], argv[1], argv[2], argv[argc-1], &cipherp, &ret)) @@ -316,19 +321,19 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg else if (argv[3] == atom_false) encflg = 0; else { - ret = ERROR_Str(env, "Bad enc flag"); + ret = EXCP_BADARG(env, "Bad enc flag"); goto ret; } if (ctx_res->ctx) { /* It is *not* a ctx_res for the compatibility handling of non-EVP aes_ctr */ if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, NULL, NULL, encflg)) { - ret = ERROR_Str(env, "Can't initialize encflag"); + ret = EXCP_ERROR(env, "Can't initialize encflag"); goto ret; } } ret = argv[0]; } else { - ret = ERROR_Str(env, "Bad 1:st arg"); + ret = EXCP_BADARG(env, "Bad 1:st arg"); goto ret; } @@ -348,7 +353,7 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ ERL_NIF_TERM ret; if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res)) - return ERROR_Str(env, "Bad 1:st arg"); + return EXCP_BADARG(env, "Bad 1:st arg"); get_update_args(env, ctx_res, argv[1], &ret); @@ -363,10 +368,10 @@ ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a ASSERT(argc <= 3); if (!enif_inspect_binary(env, argv[1], &data_bin)) - return ERROR_Str(env, "expected binary as data"); + return EXCP_BADARG(env, "expected binary as data"); if (data_bin.size > INT_MAX) - return ERROR_Str(env, "to long data"); + return EXCP_BADARG(env, "to long data"); /* Run long jobs on a dirty scheduler to not block the current emulator thread */ if (data_bin.size > MAX_BYTES_TO_NIF) { @@ -407,10 +412,10 @@ ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ASSERT(argc == 5); if (!enif_inspect_binary(env, argv[3], &data_bin)) - return ERROR_Str(env, "expected binary as data"); + return EXCP_BADARG(env, "expected binary as data"); if (data_bin.size > INT_MAX) - return ERROR_Str(env, "to long data"); + return EXCP_BADARG(env, "to long data"); /* Run long jobs on a dirty scheduler to not block the current emulator thread */ if (data_bin.size > MAX_BYTES_TO_NIF) { diff --git a/lib/crypto/c_src/atoms.c b/lib/crypto/c_src/atoms.c index 798c26c9bb..114e3c1985 100644 --- a/lib/crypto/c_src/atoms.c +++ b/lib/crypto/c_src/atoms.c @@ -33,6 +33,7 @@ ERL_NIF_TERM atom_undefined; ERL_NIF_TERM atom_ok; ERL_NIF_TERM atom_none; ERL_NIF_TERM atom_notsup; +ERL_NIF_TERM atom_badarg; ERL_NIF_TERM atom_digest; #ifdef FIPS_SUPPORT ERL_NIF_TERM atom_enabled; @@ -150,6 +151,7 @@ int init_atoms(ErlNifEnv *env, const ERL_NIF_TERM fips_mode, const ERL_NIF_TERM atom_ok = enif_make_atom(env,"ok"); atom_none = enif_make_atom(env,"none"); atom_notsup = enif_make_atom(env,"notsup"); + atom_badarg = enif_make_atom(env,"badarg"); atom_digest = enif_make_atom(env,"digest"); atom_type = enif_make_atom(env,"type"); diff --git a/lib/crypto/c_src/atoms.h b/lib/crypto/c_src/atoms.h index f8e9211459..fc46d838aa 100644 --- a/lib/crypto/c_src/atoms.h +++ b/lib/crypto/c_src/atoms.h @@ -37,6 +37,7 @@ extern ERL_NIF_TERM atom_undefined; extern ERL_NIF_TERM atom_ok; extern ERL_NIF_TERM atom_none; extern ERL_NIF_TERM atom_notsup; +extern ERL_NIF_TERM atom_badarg; extern ERL_NIF_TERM atom_digest; #ifdef FIPS_SUPPORT extern ERL_NIF_TERM atom_enabled; diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index b4e2582fc6..bd04daee5e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -538,6 +538,13 @@ poly1305(Key, Data) -> %%% %%%================================================================ +-define(COMPAT(CALL), + try CALL + catch + error:{E,_Reason} when E==notsup ; E==badarg -> + error(E) + end). + -spec cipher_info(Type) -> map() when Type :: block_cipher_with_iv() | aead_cipher() | block_cipher_without_iv(). @@ -545,7 +552,6 @@ cipher_info(Type) -> cipher_info_nif(Type). %%%---- Block ciphers - %%%---------------------------------------------------------------- -spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary(); (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) -> @@ -573,13 +579,13 @@ do_block_encrypt(Type, Key, Ivec, Data) when Type =:= aes_gcm; end; do_block_encrypt(Type, Key, Ivec, PlainText) -> - crypto_one_shot(Type, Key, Ivec, PlainText, true). + ?COMPAT(crypto_one_shot(Type, Key, Ivec, PlainText, true)). -spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). block_encrypt(Type, Key, PlainText) -> - crypto_one_shot(Type, Key, <<>>, PlainText, true). + ?COMPAT(crypto_one_shot(Type, Key, <<>>, PlainText, true)). %%%---------------------------------------------------------------- %%%---------------------------------------------------------------- @@ -599,13 +605,13 @@ do_block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm; aead_decrypt(Type, Key, Ivec, AAD, Data, Tag); do_block_decrypt(Type, Key, Ivec, Data) -> - crypto_one_shot(Type, Key, Ivec, Data, false). + ?COMPAT(crypto_one_shot(Type, Key, Ivec, Data, false)). -spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). block_decrypt(Type, Key, Data) -> - crypto_one_shot(Type, Key, <<>>, Data, false). + ?COMPAT(crypto_one_shot(Type, Key, <<>>, Data, false)). %%%-------- Stream ciphers API @@ -625,15 +631,11 @@ block_decrypt(Type, Key, Data) -> -spec stream_init(Type, Key, IVec) -> State | no_return() when Type :: stream_cipher_iv(), Key :: iodata(), - IVec :: binary(), + IVec ::binary(), State :: stream_state() . stream_init(Type, Key, IVec) when is_binary(IVec) -> - case crypto_init(Type, Key, IVec) of - {ok,Ref} -> - {Type, {Ref,flg_undefined}}; - {error,_} -> - error(badarg) - end. + Ref = ?COMPAT(crypto_init(Type, Key, IVec)), + {Type, {Ref,flg_undefined}}. -spec stream_init(Type, Key) -> State | no_return() @@ -641,12 +643,8 @@ stream_init(Type, Key, IVec) when is_binary(IVec) -> Key :: iodata(), State :: stream_state() . stream_init(rc4 = Type, Key) -> - case crypto_init(Type, Key, undefined) of - {ok,Ref} -> - {Type, {Ref,flg_undefined}}; - {error,_} -> - error(badarg) - end. + Ref = ?COMPAT(crypto_init(Type, Key, undefined)), + {Type, {Ref,flg_undefined}}. %%%---- stream_encrypt -spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return() @@ -655,7 +653,7 @@ stream_init(rc4 = Type, Key) -> NewState :: stream_state(), CipherText :: iodata() . stream_encrypt(State, Data) -> - crypto_stream_emulate(State, Data, true). + crypto_stream_emulate(State, Data, true). %%%---- stream_decrypt -spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return() @@ -664,24 +662,17 @@ stream_encrypt(State, Data) -> NewState :: stream_state(), PlainText :: iodata() . stream_decrypt(State, Data) -> - crypto_stream_emulate(State, Data, false). + crypto_stream_emulate(State, Data, false). %%%-------- helpers -crypto_stream_emulate({Cipher,{Ref,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref) -> - case crypto_init(Ref, EncryptFlag) of - {error,_} -> - error(badarg); - MaybeNewRef when is_reference(MaybeNewRef) -> - crypto_stream_emulate({Cipher,MaybeNewRef}, Data, EncryptFlag) - end; +crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) -> + ?COMPAT(begin + Ref = crypto_init(Ref0, EncryptFlag), + {{Cipher,Ref}, crypto_update(Ref, Data)} + end); crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> - case crypto_update(Ref, Data) of - {error,_} -> - error(badarg); - Bin when is_binary(Bin) -> - {{Cipher,Ref},Bin} - end. + ?COMPAT({{Cipher,Ref}, crypto_update(Ref, Data)}). %%%---------------------------------------------------------------- -spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, @@ -724,7 +715,7 @@ next_iv(Type, Data, _Ivec) -> %%% Create and initialize a new state for encryption or decryption %%% --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -736,18 +727,12 @@ crypto_init(Cipher, Key, undefined, EncryptFlag) -> crypto_init(Cipher, Key, <<>>, EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - EncryptFlag) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), + EncryptFlag). --spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} +-spec crypto_init(Cipher, Key, IV) -> State | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -755,32 +740,23 @@ crypto_init(Cipher, Key, IV, EncryptFlag) -> IV :: iodata() | undefined, State :: crypto_state() . crypto_init(Cipher, Key, undefined) -> - crypto_init(Cipher, Key, <<>>); - -crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - undefined) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), <<>>, + undefined); +crypto_init(Cipher, Key, IV) -> + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), + undefined). --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | ng_crypto_error() when Ref :: crypto_state(), EncryptFlag :: boolean() . crypto_init(Ref, EncryptFlag) when is_reference(Ref), is_atom(EncryptFlag) -> - case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of - {error,Error} -> - {error,Error}; - R when is_reference(R) -> - R - end. + ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag). %%%---------------------------------------------------------------- %%% @@ -789,7 +765,7 @@ crypto_init(Ref, EncryptFlag) when is_reference(Ref), %%% blocksize. %%% --spec crypto_update(State, Data) -> Result | {error,term()} +-spec crypto_update(State, Data) -> Result | ng_crypto_error() when State :: crypto_state(), Data :: iodata(), Result :: binary() . @@ -808,7 +784,7 @@ crypto_update(State, Data0) -> %%% The size must be an integer multiple of the crypto's blocksize. %%% --spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -825,22 +801,26 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> <<>> -> <<>>; % Known to fail on OpenSSL 0.9.8h Data -> - ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) + ng_crypto_one_shot_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), Data, + EncryptFlag) end. %%%---------------------------------------------------------------- %%% NIFs --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} - ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . +-type ng_crypto_error() :: no_return() . + +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | ng_crypto_error() + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error(). ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. --spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. --spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error(). ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%---------------------------------------------------------------- diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 14e2c4a7a7..f76076a523 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -166,31 +166,31 @@ groups() -> compute_bug]}, {ecdh, [], [use_all_elliptic_curves, compute, generate]}, {srp, [], [generate_compute]}, - {des_cbc, [], [block, api_ng]}, - {des_cfb, [], [block, api_ng]}, - {des3_cbc,[], [block, api_ng]}, - {des_ede3,[], [block, api_ng]}, - {des3_cbf,[], [block, api_ng]}, - {des3_cfb,[], [block, api_ng]}, - {rc2_cbc,[], [block, api_ng]}, - {aes_cbc128,[], [block, api_ng, cmac]}, - {aes_cfb8,[], [block, api_ng]}, - {aes_cfb128,[], [block, api_ng]}, - {aes_cbc256,[], [block, api_ng, cmac]}, - {aes_ecb,[], [block, api_ng]}, + {des_cbc, [], [block, api_ng, api_ng_one_shot]}, + {des_cfb, [], [block, api_ng, api_ng_one_shot]}, + {des3_cbc,[], [block, api_ng, api_ng_one_shot]}, + {des_ede3,[], [block, api_ng, api_ng_one_shot]}, + {des3_cbf,[], [block, api_ng, api_ng_one_shot]}, + {des3_cfb,[], [block, api_ng, api_ng_one_shot]}, + {rc2_cbc,[], [block, api_ng, api_ng_one_shot]}, + {aes_cbc128,[], [block, api_ng, api_ng_one_shot, cmac]}, + {aes_cfb8,[], [block, api_ng, api_ng_one_shot]}, + {aes_cfb128,[], [block, api_ng, api_ng_one_shot]}, + {aes_cbc256,[], [block, api_ng, api_ng_one_shot, cmac]}, + {aes_ecb,[], [block, api_ng, api_ng_one_shot]}, {aes_ige256,[], [block]}, - {blowfish_cbc, [], [block, api_ng]}, - {blowfish_ecb, [], [block, api_ng]}, - {blowfish_cfb64, [], [block, api_ng]}, - {blowfish_ofb64,[], [block, api_ng]}, - {rc4, [], [stream, api_ng]}, - {aes_ctr, [], [stream, api_ng]}, + {blowfish_cbc, [], [block, api_ng, api_ng_one_shot]}, + {blowfish_ecb, [], [block, api_ng, api_ng_one_shot]}, + {blowfish_cfb64, [], [block, api_ng, api_ng_one_shot]}, + {blowfish_ofb64,[], [block, api_ng, api_ng_one_shot]}, + {rc4, [], [stream, api_ng, api_ng_one_shot]}, + {aes_ctr, [], [stream, api_ng, api_ng_one_shot]}, {aes_ccm, [], [aead]}, {aes_gcm, [], [aead]}, {chacha20_poly1305, [], [aead]}, - {chacha20, [], [stream, api_ng]}, + {chacha20, [], [stream, api_ng, api_ng_one_shot]}, {poly1305, [], [poly1305]}, - {aes_cbc, [], [block, api_ng]}, + {aes_cbc, [], [block, api_ng, api_ng_one_shot]}, {no_aes_cfb8,[], [no_support, no_block]}, {no_aes_cfb128,[], [no_support, no_block]}, {no_md4, [], [no_support, no_hash]}, @@ -457,8 +457,8 @@ api_ng_cipher_increment({Type, Key, IV, PlainTexts}=_X) -> api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> ct:log("~p",[_X]), PlainTexts = iolistify(PlainText0), - {ok,RefEnc} = crypto:crypto_init(Type, Key, IV, true), - {ok,RefDec} = crypto:crypto_init(Type, Key, IV, false), + RefEnc = crypto:crypto_init(Type, Key, IV, true), + RefDec = crypto:crypto_init(Type, Key, IV, false), EncTexts = api_ng_cipher_increment_loop(RefEnc, PlainTexts), Enc = iolist_to_binary(EncTexts), case ExpectedEncText of @@ -480,15 +480,55 @@ api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> api_ng_cipher_increment_loop(Ref, InTexts) -> lists:map(fun(Txt) -> - case crypto:crypto_update(Ref, Txt) of + try crypto:crypto_update(Ref, Txt) + of Bin when is_binary(Bin) -> - Bin; - {error,Error} -> + Bin + catch + error:Error -> ct:pal("Txt = ~p",[Txt]), ct:fail("~p",[Error]) end end, InTexts). +%%-------------------------------------------------------------------- +api_ng_one_shot() -> + [{doc, "Test new api"}]. + +api_ng_one_shot(Config) when is_list(Config) -> + Blocks = lazy_eval(proplists:get_value(block, Config, [])), + Streams = lazy_eval(proplists:get_value(stream, Config, [])), + lists:foreach(fun do_api_ng_one_shot/1, Blocks++Streams). + +do_api_ng_one_shot({Type, Key, PlainTexts}=_X) -> + ct:log("~p",[_X]), + do_api_ng_one_shot({Type, Key, <<>>, PlainTexts}); + +do_api_ng_one_shot({Type, Key, IV, PlainTexts}=_X) -> + ct:log("~p",[_X]), + do_api_ng_one_shot({Type, Key, IV, PlainTexts, undefined}); + +do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> + ct:log("~p",[_X]), + PlainText = iolist_to_binary(PlainText0), + EncTxt = crypto:crypto_one_shot(Type, Key, IV, PlainText, true), + case ExpectedEncText of + undefined -> + ok; + EncTxt -> + ok; + OtherEnc -> + ct:log("In: ~p~nOut: ~p",[_X,OtherEnc]), + ct:fail("api_ng_one_shot (encode)",[]) + end, + case crypto:crypto_one_shot(Type, Key, IV, EncTxt, false) of + PlainText -> + ok; + OtherPT -> + ct:log("In: ~p~nOut: ~p",[_X,OtherPT]), + ct:fail("api_ng_one_shot (decode)",[]) + end. + %%-------------------------------------------------------------------- no_aead() -> [{doc, "Test disabled aead ciphers"}]. -- cgit v1.2.3 From b13f268f3e67ebe357f2bd87879e57afb45f6414 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 17:43:30 +0100 Subject: crypto: Remove compat specials from crypto_init --- lib/crypto/src/crypto.erl | 67 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'lib') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index bd04daee5e..b53d83b851 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,8 +56,8 @@ ]). %% New interface --export([crypto_init/4, crypto_init/3, crypto_init/2, - crypto_update/2, +-export([crypto_init/4, + crypto_update/2, crypto_update/3, crypto_one_shot/5 ]). @@ -634,7 +634,10 @@ block_decrypt(Type, Key, Data) -> IVec ::binary(), State :: stream_state() . stream_init(Type, Key, IVec) when is_binary(IVec) -> - Ref = ?COMPAT(crypto_init(Type, Key, IVec)), + Ref = ?COMPAT(ng_crypto_init_nif(alias(Type), + iolist_to_binary(Key), iolist_to_binary(IVec), + undefined) + ), {Type, {Ref,flg_undefined}}. @@ -643,7 +646,10 @@ stream_init(Type, Key, IVec) when is_binary(IVec) -> Key :: iodata(), State :: stream_state() . stream_init(rc4 = Type, Key) -> - Ref = ?COMPAT(crypto_init(Type, Key, undefined)), + Ref = ?COMPAT(ng_crypto_init_nif(alias(Type), + iolist_to_binary(Key), <<>>, + undefined) + ), {Type, {Ref,flg_undefined}}. %%%---- stream_encrypt @@ -667,7 +673,7 @@ stream_decrypt(State, Data) -> %%%-------- helpers crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) -> ?COMPAT(begin - Ref = crypto_init(Ref0, EncryptFlag), + Ref = ng_crypto_init_nif(Ref0, <<>>, <<>>, EncryptFlag), {{Cipher,Ref}, crypto_update(Ref, Data)} end); @@ -724,40 +730,16 @@ next_iv(Type, Data, _Ivec) -> EncryptFlag :: boolean(), State :: crypto_state() . crypto_init(Cipher, Key, undefined, EncryptFlag) -> - crypto_init(Cipher, Key, <<>>, EncryptFlag); + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), undefined, + EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag). - --spec crypto_init(Cipher, Key, IV) -> State | ng_crypto_error() - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - State :: crypto_state() . -crypto_init(Cipher, Key, undefined) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), <<>>, - undefined); - -crypto_init(Cipher, Key, IV) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), iolist_to_binary(IV), - undefined). - - --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | ng_crypto_error() - when Ref :: crypto_state(), - EncryptFlag :: boolean() . - -crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> - ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag). - %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt a sequence of bytes. The sum of the sizes @@ -778,6 +760,20 @@ crypto_update(State, Data0) -> end. +-spec crypto_update(State, Data, IV) -> Result | ng_crypto_error() + when State :: crypto_state(), + Data :: iodata(), + IV :: iodata(), + Result :: binary() . +crypto_update(State, Data0, IV) -> + %% When State is from State = crypto_init(Cipher, Key, undefined, EncryptFlag) + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) + end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. @@ -811,7 +807,7 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> -type ng_crypto_error() :: no_return() . --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | ng_crypto_error() +-spec ng_crypto_init_nif(atom(), binary(), binary()|undefined, boolean()|undefined ) -> crypto_state() | ng_crypto_error() ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error(). ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. @@ -819,6 +815,9 @@ ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. +-spec ng_crypto_update_nif(crypto_state(), binary(), binary()) -> binary() | ng_crypto_error() . +ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub. + -spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error(). ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. -- cgit v1.2.3 From 5e0d5aab3f2a61cf9d4f72cead77594c5fdde793 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 15:08:36 +0100 Subject: crypto: New function for SSL app --- lib/crypto/c_src/api_ng.c | 63 ++++++++++++++++++++++++++++++++++++++++++----- lib/crypto/c_src/cipher.h | 1 + lib/crypto/c_src/crypto.c | 1 + lib/crypto/src/crypto.erl | 3 ++- 4 files changed, 61 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 46522914b0..d970f45f94 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -120,7 +120,7 @@ static int get_init_args(ErlNifEnv* env, #endif ivec_len = GET_IV_LEN(*cipherp); - if (ivec_len) { + if (ivec_len && (ivec_arg != atom_undefined)) { if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin)) { *return_term = EXCP_BADARG(env, "Bad iv type"); @@ -134,6 +134,8 @@ static int get_init_args(ErlNifEnv* env, } } + ctx_res -> iv_len = ivec_len; + if (!((*cipherp)->cipher.p)) { #if !defined(HAVE_EVP_AES_CTR) @@ -195,11 +197,18 @@ static int get_init_args(ErlNifEnv* env, } } - if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, -1)) { - *return_term = EXCP_ERROR(env, "Can't initialize key and/or iv"); + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, NULL, -1)) { + *return_term = EXCP_ERROR(env, "Can't initialize key"); goto err; } + if (ivec_arg != atom_undefined) { + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, NULL, ivec_bin.data, -1)) { + *return_term = EXCP_ERROR(env, "Can't initialize iv"); + goto err; + } + } + EVP_CIPHER_CTX_set_padding(ctx_res->ctx, 0); *return_term = atom_ok; @@ -348,21 +357,63 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Context, Data) */ +{/* (Context, Data [, IV]) */ struct evp_cipher_ctx *ctx_res; ERL_NIF_TERM ret; if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res)) return EXCP_BADARG(env, "Bad 1:st arg"); - get_update_args(env, ctx_res, argv[1], &ret); + if (argc == 3) { + struct evp_cipher_ctx ctx_res_copy; + ErlNifBinary ivec_bin; + memcpy(&ctx_res_copy, ctx_res, sizeof(ctx_res_copy)); + ctx_res = &ctx_res_copy; + if (!enif_inspect_iolist_as_binary(env, argv[2], &ivec_bin)) + { + ret = EXCP_BADARG(env, "Bad iv type"); + goto err; + } + + if (ctx_res_copy.iv_len != ivec_bin.size) + { + ret = EXCP_BADARG(env, "Bad iv size"); + printf("Expect %d\r\n", ctx_res_copy.iv_len); + goto err; + } + +#if !defined(HAVE_EVP_AES_CTR) + // enif_fprintf(stdout, "%s:%u state = %T\r\n", __FILE__, __LINE__, ctx_res->state); + if ((ctx_res_copy.state != atom_undefined) ) { + /* replace the iv in state with argv[2] */ + ERL_NIF_TERM state0; + const ERL_NIF_TERM *tuple_argv; + int tuple_argc; + state0 = enif_make_copy(env, ctx_res_copy.state); + if (enif_get_tuple(env, state0, &tuple_argc, &tuple_argv) && (tuple_argc == 4)) { + /* A compatibility state term */ + ctx_res_copy.state = enif_make_tuple4(env, tuple_argv[0], argv[2], tuple_argv[2], tuple_argv[3]); + } + } else +#endif + if (!EVP_CipherInit_ex(ctx_res_copy.ctx, NULL, NULL, NULL, ivec_bin.data, -1)) + { + ret = EXCP_ERROR(env, "Can't set iv"); + goto err; + } + + get_update_args(env, &ctx_res_copy, argv[1], &ret); + } else + get_update_args(env, ctx_res, argv[1], &ret); + + err: return ret; /* Both success and error */ } ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Context, Data) */ +{/* (Context, Data [, IV]) */ ErlNifBinary data_bin; ASSERT(argc <= 3); diff --git a/lib/crypto/c_src/cipher.h b/lib/crypto/c_src/cipher.h index f7b1a09f21..b94873940f 100644 --- a/lib/crypto/c_src/cipher.h +++ b/lib/crypto/c_src/cipher.h @@ -59,6 +59,7 @@ struct cipher_type_t { extern ErlNifResourceType* evp_cipher_ctx_rtype; struct evp_cipher_ctx { EVP_CIPHER_CTX* ctx; + int iv_len; #if !defined(HAVE_EVP_AES_CTR) ErlNifEnv* env; ERL_NIF_TERM state; diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 501c1ffb42..4aed06a489 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -80,6 +80,7 @@ static ErlNifFunc nif_funcs[] = { {"aes_ige_crypt_nif", 4, aes_ige_crypt_nif, 0}, {"ng_crypto_init_nif", 4, ng_crypto_init_nif, 0}, {"ng_crypto_update_nif", 2, ng_crypto_update_nif, 0}, + {"ng_crypto_update_nif", 3, ng_crypto_update_nif, 0}, {"ng_crypto_one_shot_nif", 5, ng_crypto_one_shot_nif, 0}, {"strong_rand_bytes_nif", 1, strong_rand_bytes_nif, 0}, {"strong_rand_range_nif", 1, strong_rand_range_nif, 0}, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index b53d83b851..4bceeb7510 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,7 +56,7 @@ ]). %% New interface --export([crypto_init/4, +-export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, crypto_update/3, crypto_one_shot/5 ]). @@ -774,6 +774,7 @@ crypto_update(State, Data0, IV) -> ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. -- cgit v1.2.3 From 5a313cb363e2f74ed0c602482c609fcc6dcc718a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Mar 2019 15:07:43 +0100 Subject: crypto: Rename SSL special functions to crypto_init_dyn_iv/3 and crypto_update_dyn_iv/3 --- lib/crypto/src/crypto.erl | 63 ++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 4bceeb7510..5cf34f8069 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,9 +56,11 @@ ]). %% New interface --export([crypto_init/4, crypto_init/3, crypto_init/2, - crypto_update/2, crypto_update/3, - crypto_one_shot/5 +-export([crypto_init/4, crypto_init/3, + crypto_update/2, + crypto_one_shot/5, + crypto_init_dyn_iv/3, + crypto_update_dyn_iv/3 ]). @@ -721,24 +723,39 @@ next_iv(Type, Data, _Ivec) -> %%% Create and initialize a new state for encryption or decryption %%% +-spec crypto_init(Cipher, Key, EncryptFlag) -> State | ng_crypto_error() + when Cipher :: block_cipher_without_iv() + | stream_cipher_no_iv(), + Key :: iodata(), + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init(Cipher, Key, EncryptFlag) -> + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), <<>>, EncryptFlag). + + -spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error() - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), + when Cipher :: stream_cipher_iv() + | block_cipher_with_iv(), Key :: iodata(), - IV :: iodata() | undefined, + IV :: iodata(), EncryptFlag :: boolean(), State :: crypto_state() . -crypto_init(Cipher, Key, undefined, EncryptFlag) -> - %% The IV is supposed to be supplied by calling crypto_update/3 - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), undefined, - EncryptFlag); - crypto_init(Cipher, Key, IV, EncryptFlag) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), iolist_to_binary(IV), - EncryptFlag). + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag). + + + +%%%---------------------------------------------------------------- +-spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | ng_crypto_error() + when Cipher :: stream_cipher_iv() + | block_cipher_with_iv(), + Key :: iodata(), + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), undefined, EncryptFlag). %%%---------------------------------------------------------------- %%% @@ -760,12 +777,13 @@ crypto_update(State, Data0) -> end. --spec crypto_update(State, Data, IV) -> Result | ng_crypto_error() - when State :: crypto_state(), - Data :: iodata(), - IV :: iodata(), - Result :: binary() . -crypto_update(State, Data0, IV) -> +%%%---------------------------------------------------------------- +-spec crypto_update_dyn_iv(State, Data, IV) -> Result | ng_crypto_error() + when State :: crypto_state(), + Data :: iodata(), + IV :: iodata(), + Result :: binary() . +crypto_update_dyn_iv(State, Data0, IV) -> %% When State is from State = crypto_init(Cipher, Key, undefined, EncryptFlag) case iolist_to_binary(Data0) of <<>> -> @@ -774,7 +792,6 @@ crypto_update(State, Data0, IV) -> ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) end. - %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. -- cgit v1.2.3 From 7bcd1c7f70c70cb09e053510087b27728793caa6 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 17:13:58 +0100 Subject: crypto: Testcase for TLS using new API --- lib/crypto/test/crypto_SUITE.erl | 95 +++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index f76076a523..bd540329b5 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -166,31 +166,31 @@ groups() -> compute_bug]}, {ecdh, [], [use_all_elliptic_curves, compute, generate]}, {srp, [], [generate_compute]}, - {des_cbc, [], [block, api_ng, api_ng_one_shot]}, - {des_cfb, [], [block, api_ng, api_ng_one_shot]}, - {des3_cbc,[], [block, api_ng, api_ng_one_shot]}, - {des_ede3,[], [block, api_ng, api_ng_one_shot]}, - {des3_cbf,[], [block, api_ng, api_ng_one_shot]}, - {des3_cfb,[], [block, api_ng, api_ng_one_shot]}, - {rc2_cbc,[], [block, api_ng, api_ng_one_shot]}, - {aes_cbc128,[], [block, api_ng, api_ng_one_shot, cmac]}, - {aes_cfb8,[], [block, api_ng, api_ng_one_shot]}, - {aes_cfb128,[], [block, api_ng, api_ng_one_shot]}, - {aes_cbc256,[], [block, api_ng, api_ng_one_shot, cmac]}, - {aes_ecb,[], [block, api_ng, api_ng_one_shot]}, + {des_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {des_cfb, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {des3_cbc,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {des_ede3,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {des3_cbf,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {des3_cfb,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {rc2_cbc,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {aes_cbc128,[], [block, api_ng, api_ng_one_shot, api_ng_tls, cmac]}, + {aes_cfb8,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {aes_cfb128,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {aes_cbc256,[], [block, api_ng, api_ng_one_shot, api_ng_tls, cmac]}, + {aes_ecb,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, {aes_ige256,[], [block]}, - {blowfish_cbc, [], [block, api_ng, api_ng_one_shot]}, - {blowfish_ecb, [], [block, api_ng, api_ng_one_shot]}, - {blowfish_cfb64, [], [block, api_ng, api_ng_one_shot]}, - {blowfish_ofb64,[], [block, api_ng, api_ng_one_shot]}, - {rc4, [], [stream, api_ng, api_ng_one_shot]}, - {aes_ctr, [], [stream, api_ng, api_ng_one_shot]}, + {blowfish_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {blowfish_ecb, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {blowfish_cfb64, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {blowfish_ofb64,[], [block, api_ng, api_ng_one_shot, api_ng_tls]}, + {rc4, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]}, + {aes_ctr, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]}, {aes_ccm, [], [aead]}, {aes_gcm, [], [aead]}, {chacha20_poly1305, [], [aead]}, - {chacha20, [], [stream, api_ng, api_ng_one_shot]}, + {chacha20, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]}, {poly1305, [], [poly1305]}, - {aes_cbc, [], [block, api_ng, api_ng_one_shot]}, + {aes_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, {no_aes_cfb8,[], [no_support, no_block]}, {no_aes_cfb128,[], [no_support, no_block]}, {no_md4, [], [no_support, no_hash]}, @@ -529,6 +529,61 @@ do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> ct:fail("api_ng_one_shot (decode)",[]) end. +%%-------------------------------------------------------------------- +api_ng_tls() -> + [{doc, "Test special tls api"}]. + +api_ng_tls(Config) when is_list(Config) -> + Blocks = lazy_eval(proplists:get_value(block, Config, [])), + Streams = lazy_eval(proplists:get_value(stream, Config, [])), + lists:foreach(fun do_api_ng_tls/1, Blocks++Streams). + + +do_api_ng_tls({Type, Key, PlainTexts}=_X) -> + ct:log("~p",[_X]), + do_api_ng_tls({Type, Key, <<>>, PlainTexts}); + +do_api_ng_tls({Type, Key, IV, PlainTexts}=_X) -> + ct:log("~p",[_X]), + do_api_ng_tls({Type, Key, IV, PlainTexts, undefined}); + +do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> + ct:log("~p",[_X]), + PlainText = iolist_to_binary(PlainText0), + Renc = crypto:crypto_init_dyn_iv(Type, Key, true), + Rdec = crypto:crypto_init_dyn_iv(Type, Key, false), + EncTxt = crypto:crypto_update_dyn_iv(Renc, PlainText, IV), + case ExpectedEncText of + undefined -> + ok; + EncTxt -> + %% Now check that the state is NOT updated: + case crypto:crypto_update_dyn_iv(Renc, PlainText, IV) of + EncTxt -> + ok; + EncTxt2 -> + ct:log("In = ~p,~nEncTxt = ~p~nEncTxt2= ~p", [_X,EncTxt,EncTxt2]), + ct:fail("api_ng_tls (second encode)",[]) + end; + OtherEnc -> + ct:log("In: ~p~nOut: ~p",[_X,OtherEnc]), + ct:fail("api_ng_tls (encode)",[]) + end, + case crypto:crypto_update_dyn_iv(Rdec, EncTxt, IV) of + PlainText -> + %% Now check that the state is NOT updated: + case crypto:crypto_update_dyn_iv(Rdec, EncTxt, IV) of + PlainText -> + ok; + PlainText2 -> + ct:log("In = ~p,~nPlainText = ~p~nPlainText2= ~p", [_X,PlainText,PlainText2]), + ct:fail("api_ng_tls (second decode)",[]) + end; + OtherPT -> + ct:log("In: ~p~nOut: ~p",[_X,OtherPT]), + ct:fail("api_ng_tlst (decode)",[]) + end. + %%-------------------------------------------------------------------- no_aead() -> [{doc, "Test disabled aead ciphers"}]. -- cgit v1.2.3 From 00dcdf6c9aec2a78f15bf673f56a1c044103b23e Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 19:54:45 +0100 Subject: crypto: Fix leak for eddsa detected by Valgrind --- lib/crypto/c_src/pkey.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/crypto/c_src/pkey.c b/lib/crypto/c_src/pkey.c index 393358d173..638bb588fa 100644 --- a/lib/crypto/c_src/pkey.c +++ b/lib/crypto/c_src/pkey.c @@ -719,6 +719,11 @@ enif_get_atom(env,argv[1],buf,1024,ERL_NIF_LATIN1); printf("hash=%s ",buf); if (pkey) EVP_PKEY_free(pkey); +#ifdef HAVE_EDDSA + if (mdctx) + EVP_MD_CTX_free(mdctx); +#endif + return ret; } -- cgit v1.2.3 From 27882b21c33396135ff7789cc14cc782c0c0e318 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Mar 2019 15:52:41 +0100 Subject: crypto: Fix bug for older cryptolib --- lib/crypto/c_src/api_ng.c | 89 ++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 35 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index d970f45f94..393fee31ef 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -107,19 +107,37 @@ static int get_init_args(ErlNifEnv* env, *return_term = EXCP_NOTSUP(env, "Forbidden in FIPS"); goto err; } - - /* Fetch IV */ -#if !defined(HAVE_EVP_AES_CTR) - /* This is code for OpenSSL 0.9.8. Therefore we could accept some ineficient code */ - ctx_res->env = NULL; - ctx_res->state = atom_undefined; - if (!((*cipherp)->cipher.p) && (*cipherp)->flags & AES_CTR_COMPAT) - ivec_len = 16; - else -#endif + /* Get ivec_len for this cipher (if we found one) */ +#if !defined(HAVE_EVP_AES_CTR) + /* This code is for historic OpenSSL where EVP_aes_*_ctr is not defined.... */ + if ((*cipherp)->cipher.p) { + /* Not aes_ctr compatibility code since EVP_* + was defined and assigned to (*cipherp)->cipher.p */ ivec_len = GET_IV_LEN(*cipherp); + } else { + /* No EVP_* was found */ + if ((*cipherp)->flags & AES_CTR_COMPAT) + /* Use aes_ctr compatibility code later */ + ivec_len = 16; + else { + /* Unsupported crypto */ + *return_term = EXCP_NOTSUP(env, "Unsupported cipher"); + goto err; + } + } +#else + /* Normal code */ + if (!((*cipherp)->cipher.p)) { + *return_term = EXCP_NOTSUP(env, "Unsupported cipher"); + goto err; + } + ivec_len = GET_IV_LEN(*cipherp); +#endif + + /* (*cipherp)->cipher.p != NULL and ivec_len has a value */ + /* Fetch IV */ if (ivec_len && (ivec_arg != atom_undefined)) { if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin)) { @@ -134,35 +152,36 @@ static int get_init_args(ErlNifEnv* env, } } - ctx_res -> iv_len = ivec_len; + ctx_res->iv_len = ivec_len; - if (!((*cipherp)->cipher.p)) - { #if !defined(HAVE_EVP_AES_CTR) - if ((*cipherp)->flags & AES_CTR_COMPAT) - { - ERL_NIF_TERM ecount_bin; - unsigned char *outp; - if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) { - *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin"); - goto err; - } - memset(outp, 0, AES_BLOCK_SIZE); - - ctx_res->env = enif_alloc_env(); - if (!ctx_res->env) { - *return_term = EXCP_ERROR(env, "Can't allocate env"); - goto err; - } - ctx_res->state = - enif_make_copy(ctx_res->env, - enif_make_tuple4(env, key_arg, ivec_arg, ecount_bin, enif_make_int(env, 0))); - goto success; - } -#endif - *return_term = EXCP_NOTSUP(env, "Cipher"); + if (!((*cipherp)->cipher.p) + && ((*cipherp)->flags & AES_CTR_COMPAT) + ) { + /* Must use aes_ctr compatibility code */ + ERL_NIF_TERM ecount_bin; + unsigned char *outp; + if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) { + *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin"); goto err; } + memset(outp, 0, AES_BLOCK_SIZE); + + ctx_res->env = enif_alloc_env(); + if (!ctx_res->env) { + *return_term = EXCP_ERROR(env, "Can't allocate env"); + goto err; + } + ctx_res->state = + enif_make_copy(ctx_res->env, + enif_make_tuple4(env, key_arg, ivec_arg, ecount_bin, enif_make_int(env, 0))); + goto success; + } else { + /* Flag for subsequent calls that no aes_ctr compatibility code should be called */ + ctx_res->state = atom_undefined; + ctx_res->env = NULL; + } +#endif /* Initialize the EVP_CIPHER_CTX */ -- cgit v1.2.3 From 7281dd92eb48280c25a8342547d70c867f6d731a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Mar 2019 16:16:36 +0100 Subject: crypto: Better error descriptions --- lib/crypto/c_src/api_ng.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 393fee31ef..2823b2714b 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -98,7 +98,10 @@ static int get_init_args(ErlNifEnv* env, if (!(*cipherp = get_cipher_type(cipher_arg, key_bin.size))) { - *return_term = EXCP_BADARG(env, "Unknown cipher or bad key size for the cipher"); + if (!get_cipher_type_no_key(cipher_arg)) + *return_term = EXCP_BADARG(env, "Unknown cipher"); + else + *return_term = EXCP_BADARG(env, "Bad key size"); goto err; } @@ -122,14 +125,14 @@ static int get_init_args(ErlNifEnv* env, ivec_len = 16; else { /* Unsupported crypto */ - *return_term = EXCP_NOTSUP(env, "Unsupported cipher"); + *return_term = EXCP_NOTSUP(env, "Cipher not supported in this libcrypto version"); goto err; } } #else /* Normal code */ if (!((*cipherp)->cipher.p)) { - *return_term = EXCP_NOTSUP(env, "Unsupported cipher"); + *return_term = EXCP_NOTSUP(env, "Cipher not supported in this libcrypto version"); goto err; } ivec_len = GET_IV_LEN(*cipherp); -- cgit v1.2.3 From 86cd8b95b704ac236d02f31a92545ca996816c2c Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 14 Mar 2019 19:56:51 +0100 Subject: crypto: Fix bug in ng_api --- lib/crypto/c_src/api_ng.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 2823b2714b..f727b5e90f 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -218,18 +218,22 @@ static int get_init_args(ErlNifEnv* env, goto err; } } - - if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, NULL, -1)) { - *return_term = EXCP_ERROR(env, "Can't initialize key"); - goto err; - } - - if (ivec_arg != atom_undefined) { - if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, NULL, ivec_bin.data, -1)) { - *return_term = EXCP_ERROR(env, "Can't initialize iv"); - goto err; + // enif_fprintf(stderr, "%s:%u %T %T %u\r\n", __FILE__, __LINE__, cipher_arg, ivec_arg, ivec_len); + if (ivec_arg == atom_undefined || ivec_len == 0) + { + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, NULL, -1)) { + *return_term = EXCP_ERROR(env, "Can't initialize key"); + goto err; + } } - } + else + if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, -1)) + { + *return_term = EXCP_ERROR(env, "Can't initialize key or iv"); + goto err; + } + + // enif_fprintf(stderr, "%s:%u\r\n", __FILE__, __LINE__); EVP_CIPHER_CTX_set_padding(ctx_res->ctx, 0); -- cgit v1.2.3 From 4cf7703e671a522cafd86b6efc81b8b6775e0077 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 15 Mar 2019 11:55:29 +0100 Subject: crypto: Handle EVP_CIPHER_CTX copying correctly --- lib/crypto/c_src/api_ng.c | 65 ++++++++++++++++++++++++++++++++++----- lib/crypto/c_src/openssl_config.h | 1 + 2 files changed, 59 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index f727b5e90f..6315a03ade 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -218,7 +218,7 @@ static int get_init_args(ErlNifEnv* env, goto err; } } - // enif_fprintf(stderr, "%s:%u %T %T %u\r\n", __FILE__, __LINE__, cipher_arg, ivec_arg, ivec_len); + if (ivec_arg == atom_undefined || ivec_len == 0) { if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, NULL, -1)) { @@ -233,8 +233,6 @@ static int get_init_args(ErlNifEnv* env, goto err; } - // enif_fprintf(stderr, "%s:%u\r\n", __FILE__, __LINE__); - EVP_CIPHER_CTX_set_padding(ctx_res->ctx, 0); *return_term = atom_ok; @@ -270,7 +268,6 @@ static int get_update_args(ErlNifEnv* env, ASSERT(in_data_bin.size <= INT_MAX); #if !defined(HAVE_EVP_AES_CTR) - // enif_fprintf(stdout, "%s:%u state = %T\r\n", __FILE__, __LINE__, ctx_res->state); if (ctx_res->state != atom_undefined) { ERL_NIF_TERM state0, newstate_and_outdata; const ERL_NIF_TERM *tuple_argv; @@ -381,6 +378,48 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg /* Encrypt/decrypt */ /*************************************************************************/ +#if !defined(HAVE_EVP_CIPHER_CTX_COPY) +/* + The EVP_CIPHER_CTX_copy is not available in older cryptolibs although + the function is needed. + Instead of implement it in-place, we have a copy here as a compatibility + function +*/ + +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); + +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) +{ + if ((in == NULL) || (in->cipher == NULL)) + { + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a cipher context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) + return 0; +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out,in,sizeof *out); + + if (in->cipher_data && in->cipher->ctx_size) + { + out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) + return 0; + memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size); + } + +#if defined(EVP_CIPH_CUSTOM_COPY) && defined(EVP_CTRL_COPY) + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) + return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); +#endif + return 1; +} +/****** End of compatibility function ******/ +#endif + ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Context, Data [, IV]) */ @@ -393,7 +432,21 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ if (argc == 3) { struct evp_cipher_ctx ctx_res_copy; ErlNifBinary ivec_bin; - memcpy(&ctx_res_copy, ctx_res, sizeof(ctx_res_copy)); + + memcpy(&ctx_res_copy, ctx_res, sizeof ctx_res_copy); +#if !defined(HAVE_EVP_AES_CTR) + if (ctx_res_copy.state == atom_undefined) + /* Not going to use aes_ctr compat functions */ +#endif + { + ctx_res_copy.ctx = EVP_CIPHER_CTX_new(); + + if (!EVP_CIPHER_CTX_copy(ctx_res_copy.ctx, ctx_res->ctx)) { + ret = EXCP_ERROR(env, "Can't copy ctx_res"); + goto err; + } + } + ctx_res = &ctx_res_copy; if (!enif_inspect_iolist_as_binary(env, argv[2], &ivec_bin)) @@ -405,12 +458,10 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ if (ctx_res_copy.iv_len != ivec_bin.size) { ret = EXCP_BADARG(env, "Bad iv size"); - printf("Expect %d\r\n", ctx_res_copy.iv_len); goto err; } #if !defined(HAVE_EVP_AES_CTR) - // enif_fprintf(stdout, "%s:%u state = %T\r\n", __FILE__, __LINE__, ctx_res->state); if ((ctx_res_copy.state != atom_undefined) ) { /* replace the iv in state with argv[2] */ ERL_NIF_TERM state0; diff --git a/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h index 1c138e3bd1..46868cb987 100644 --- a/lib/crypto/c_src/openssl_config.h +++ b/lib/crypto/c_src/openssl_config.h @@ -109,6 +109,7 @@ #ifndef HAS_LIBRESSL # if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0) # define HAS_EVP_PKEY_CTX +# define HAVE_EVP_CIPHER_CTX_COPY # endif #endif -- cgit v1.2.3 From ac19d9534c7c9edf699107c1b2994f2077633562 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 18 Mar 2019 10:13:13 +0100 Subject: crypto: Wrong ifdef symbol used for ENGINE --- lib/crypto/c_src/api_ng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c index 6315a03ade..6a833a0984 100644 --- a/lib/crypto/c_src/api_ng.c +++ b/lib/crypto/c_src/api_ng.c @@ -394,7 +394,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { return 0; } -#ifndef OPENSSL_NO_ENGINE +#ifdef HAS_ENGINE_SUPPORT /* Make sure it's safe to copy a cipher context using an ENGINE */ if (in->engine && !ENGINE_init(in->engine)) return 0; -- cgit v1.2.3 From db9fe93ef8567e7084778adbd159fe6045f61c22 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Mar 2019 15:53:08 +0100 Subject: crypto: Better error report in crypto_SUITE --- lib/crypto/test/crypto_SUITE.erl | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index bd540329b5..dfce887d87 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -466,15 +466,17 @@ api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> ok; Enc -> ok; - OtherEnc -> - ct:fail({{crypto, api_ng_encrypt, [IV,EncTexts]}, {expected, ExpectedEncText}, {got, OtherEnc}}) + _ -> + ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainTexts}, ExpectedEncText, Enc]), + ct:fail("api_ng_cipher_increment (encode)",[]) end, Plain = iolist_to_binary(PlainTexts), case iolist_to_binary(api_ng_cipher_increment_loop(RefDec, EncTexts)) of Plain -> ok; OtherPT -> - ct:fail({{crypto, api_ng_decrypt, [IV,EncTexts]}, {expected, Plain}, {got, OtherPT}}) + ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTexts}, Plain, OtherPT]), + ct:fail("api_ng_cipher_increment (encode)",[]) end. @@ -517,15 +519,15 @@ do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> ok; EncTxt -> ok; - OtherEnc -> - ct:log("In: ~p~nOut: ~p",[_X,OtherEnc]), + _ -> + ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, EncTxt]), ct:fail("api_ng_one_shot (encode)",[]) end, case crypto:crypto_one_shot(Type, Key, IV, EncTxt, false) of PlainText -> ok; OtherPT -> - ct:log("In: ~p~nOut: ~p",[_X,OtherPT]), + ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]), ct:fail("api_ng_one_shot (decode)",[]) end. @@ -562,11 +564,11 @@ do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> EncTxt -> ok; EncTxt2 -> - ct:log("In = ~p,~nEncTxt = ~p~nEncTxt2= ~p", [_X,EncTxt,EncTxt2]), + ct:log("2nd encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, EncTxt, EncTxt2]), ct:fail("api_ng_tls (second encode)",[]) end; OtherEnc -> - ct:log("In: ~p~nOut: ~p",[_X,OtherEnc]), + ct:log("1st encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, OtherEnc]), ct:fail("api_ng_tls (encode)",[]) end, case crypto:crypto_update_dyn_iv(Rdec, EncTxt, IV) of @@ -576,11 +578,11 @@ do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) -> PlainText -> ok; PlainText2 -> - ct:log("In = ~p,~nPlainText = ~p~nPlainText2= ~p", [_X,PlainText,PlainText2]), + ct:log("2nd decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, PlainText2]), ct:fail("api_ng_tls (second decode)",[]) end; OtherPT -> - ct:log("In: ~p~nOut: ~p",[_X,OtherPT]), + ct:log("1st decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]), ct:fail("api_ng_tlst (decode)",[]) end. -- cgit v1.2.3 From 4ff2ec4fcbdd9678cbeba3ccc10f0b52f9d92fc2 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 15 Mar 2019 12:27:37 +0100 Subject: crypto: Sort ciphers in alphabetic order in testsuite --- lib/crypto/test/crypto_SUITE.erl | 119 ++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 53 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index dfce887d87..7bbb05a50c 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -46,53 +46,67 @@ all() -> ]. groups() -> - [{non_fips, [], [{group, md4}, + [{non_fips, [], [ + {group, blake2b}, + {group, blake2s}, + {group, dss}, + {group, ecdsa}, + {group, ed25519}, + {group, ed448}, + {group, rsa}, + + {group, md4}, {group, md5}, {group, ripemd160}, - {group, sha}, {group, sha224}, {group, sha256}, {group, sha384}, - {group, sha512}, {group, sha3_224}, {group, sha3_256}, {group, sha3_384}, {group, sha3_512}, - {group, blake2b}, - {group, blake2s}, - {group, rsa}, - {group, dss}, - {group, ecdsa}, - {group, ed25519}, - {group, ed448}, + {group, sha512}, + {group, sha}, + {group, dh}, {group, ecdh}, {group, srp}, - {group, des_cbc}, - {group, des_cfb}, - {group, des3_cbc}, - {group, des3_cbf}, - {group, des3_cfb}, - {group, des_ede3}, - {group, blowfish_cbc}, - {group, blowfish_ecb}, - {group, blowfish_cfb64}, - {group, blowfish_ofb64}, - {group, aes_cbc128}, - {group, aes_cfb8}, - {group, aes_cfb128}, - {group, aes_cbc256}, - {group, aes_ige256}, - {group, rc2_cbc}, - {group, rc4}, - {group, aes_ctr}, + + {group, aes_cbc}, {group, aes_ccm}, {group, aes_gcm}, {group, chacha20_poly1305}, {group, chacha20}, + {group, des3_cfb}, + {group, aes_cbc128}, + {group, aes_cbc256}, + {group, aes_cfb128}, + {group, aes_cfb8}, + {group, aes_ctr}, + {group, aes_ige256}, + {group, blowfish_cbc}, + {group, blowfish_cfb64}, + {group, blowfish_ecb}, + {group, blowfish_ofb64}, + {group, des3_cbc}, + {group, des3_cbf}, + {group, des_cbc}, + {group, des_cfb}, + {group, des_ede3}, {group, poly1305}, - {group, aes_cbc}]}, - {fips, [], [{group, no_md4}, + {group, rc2_cbc}, + {group, rc4} + ]}, + {fips, [], [ + %% {group, no_blake2b}, + %% {group, no_blake2s}, + {group, dss}, + {group, ecdsa}, + {group, no_ed25519}, + {group, no_ed448}, + {group, rsa}, + + {group, no_md4}, {group, no_md5}, {group, no_ripemd160}, {group, sha}, @@ -100,37 +114,36 @@ groups() -> {group, sha256}, {group, sha384}, {group, sha512}, - {group, rsa}, - {group, dss}, - {group, ecdsa}, - {group, no_ed25519}, - {group, no_ed448}, + {group, dh}, {group, ecdh}, {group, no_srp}, - {group, no_des_cbc}, - {group, no_des_cfb}, - {group, des3_cbc}, - {group, des3_cbf}, + + {group, aes_cbc}, + {group, aes_ccm}, + {group, aes_gcm}, + {group, no_chacha20_poly1305}, + {group, no_chacha20}, {group, des3_cfb}, - {group, des_ede3}, - {group, no_blowfish_cbc}, - {group, no_blowfish_ecb}, - {group, no_blowfish_cfb64}, - {group, no_blowfish_ofb64}, {group, aes_cbc128}, - {group, no_aes_cfb8}, - {group, no_aes_cfb128}, {group, aes_cbc256}, + {group, no_aes_cfb128}, + {group, no_aes_cfb8}, + {group, aes_ctr}, {group, no_aes_ige256}, + {group, no_blowfish_cbc}, + {group, no_blowfish_cfb64}, + {group, no_blowfish_ecb}, + {group, no_blowfish_ofb64}, + {group, des3_cbc}, + {group, des3_cbf}, + {group, no_des_cbc}, + {group, no_des_cfb}, + {group, des_ede3}, + %% {group, no_poly1305}, {group, no_rc2_cbc}, - {group, no_rc4}, - {group, aes_ctr}, - {group, aes_ccm}, - {group, aes_gcm}, - {group, no_chacha20_poly1305}, - {group, no_chacha20}, - {group, aes_cbc}]}, + {group, no_rc4} + ]}, {md4, [], [hash]}, {md5, [], [hash, hmac]}, {ripemd160, [], [hash]}, -- cgit v1.2.3 From 449527eb8db8b240569bbc258a3193ea448a059d Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 15 Mar 2019 17:44:10 +0100 Subject: crypto: Add FIPS testing for a couple of algorithms in crypto_SUITE. --- lib/crypto/test/crypto_SUITE.erl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 7bbb05a50c..7dbbde68e9 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -98,8 +98,8 @@ groups() -> {group, rc4} ]}, {fips, [], [ - %% {group, no_blake2b}, - %% {group, no_blake2s}, + {group, no_blake2b}, + {group, no_blake2s}, {group, dss}, {group, ecdsa}, {group, no_ed25519}, @@ -140,7 +140,7 @@ groups() -> {group, no_des_cbc}, {group, no_des_cfb}, {group, des_ede3}, - %% {group, no_poly1305}, + {group, no_poly1305}, {group, no_rc2_cbc}, {group, no_rc4} ]}, @@ -158,6 +158,8 @@ groups() -> {sha3_512, [], [hash, hmac]}, {blake2b, [], [hash, hmac]}, {blake2s, [], [hash, hmac]}, + {no_blake2b, [], [no_hash, no_hmac]}, + {no_blake2s, [], [no_hash, no_hmac]}, {rsa, [], [sign_verify, public_encrypt, private_encrypt, @@ -203,6 +205,7 @@ groups() -> {chacha20_poly1305, [], [aead]}, {chacha20, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]}, {poly1305, [], [poly1305]}, + {no_poly1305, [], [no_poly1305]}, {aes_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]}, {no_aes_cfb8,[], [no_support, no_block]}, {no_aes_cfb128,[], [no_support, no_block]}, @@ -424,6 +427,16 @@ poly1305(Config) -> end end, proplists:get_value(poly1305, Config)). +%%-------------------------------------------------------------------- +no_poly1305() -> + [{doc, "Test disabled poly1305 function"}]. +no_poly1305(Config) -> + Type = ?config(type, Config), + Key = <<133,214,190,120,87,85,109,51,127,68,82,254,66,213,6,168,1, + 3,128,138,251,13,178,253,74,191,246,175,65,73,245,27>>, + Txt = <<"Cryptographic Forum Research Group">>, + notsup(fun crypto:poly1305/2, [Key,Txt]). + %%-------------------------------------------------------------------- block() -> [{doc, "Test block ciphers"}]. -- cgit v1.2.3