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 + 3 files changed, 59 insertions(+), 6 deletions(-) (limited to 'lib/crypto/c_src') 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}, -- cgit v1.2.3