diff options
author | Doug Hogan <[email protected]> | 2019-01-03 18:14:55 -0800 |
---|---|---|
committer | Doug Hogan <[email protected]> | 2019-01-08 00:08:22 -0800 |
commit | 10665143d538b0ed344d172655e174713da3a336 (patch) | |
tree | e5bd1571863909ba2296c46b03fb0237a20f2425 | |
parent | bf063a86501f47cbfa89475aefe5bfacde56a3c9 (diff) | |
download | otp-10665143d538b0ed344d172655e174713da3a336.tar.gz otp-10665143d538b0ed344d172655e174713da3a336.tar.bz2 otp-10665143d538b0ed344d172655e174713da3a336.zip |
Revamp chacha20_stream_crypt()
* Check return values on all OpenSSL and Erlang calls.
* Remove trailing semicolon after function definition.
-rw-r--r-- | lib/crypto/c_src/chacha20.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/lib/crypto/c_src/chacha20.c b/lib/crypto/c_src/chacha20.c index 587c0cea53..03b8589524 100644 --- a/lib/crypto/c_src/chacha20.c +++ b/lib/crypto/c_src/chacha20.c @@ -74,28 +74,49 @@ ERL_NIF_TERM chacha20_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM a 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, *new_ctx; + struct evp_cipher_ctx *ctx = NULL, *new_ctx = NULL; ErlNifBinary data_bin; ERL_NIF_TERM ret, cipher_term; unsigned char *out; int outl = 0; - if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx) - || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { - return enif_make_badarg(env); - } - new_ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx)); - new_ctx->ctx = EVP_CIPHER_CTX_new(); - EVP_CIPHER_CTX_copy(new_ctx->ctx, ctx->ctx); - out = enif_make_new_binary(env, data_bin.size, &cipher_term); - EVP_CipherUpdate(new_ctx->ctx, out, &outl, data_bin.data, data_bin.size); + if (argc != 2) + goto bad_arg; + 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 == 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: enif_release_resource(new_ctx); - CONSUME_REDS(env,data_bin); return ret; + #else return enif_raise_exception(env, atom_notsup); #endif -}; +} |