aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src/hmac.c
diff options
context:
space:
mode:
authorDoug Hogan <[email protected]>2019-01-03 22:35:26 -0800
committerDoug Hogan <[email protected]>2019-01-08 01:11:58 -0800
commit7dd82475ac2c5d479e43442c88be2920af755acc (patch)
tree0ba7fbb0abeb0ae361a4fa1a2ca7926a3ec8d4e2 /lib/crypto/c_src/hmac.c
parent409caa2110638391f25a10e9146fe193bec36cf8 (diff)
downloadotp-7dd82475ac2c5d479e43442c88be2920af755acc.tar.gz
otp-7dd82475ac2c5d479e43442c88be2920af755acc.tar.bz2
otp-7dd82475ac2c5d479e43442c88be2920af755acc.zip
Revamp hmac_nif()
* Add error handling for all Erlang calls. * Add sanity check via bounds checking
Diffstat (limited to 'lib/crypto/c_src/hmac.c')
-rw-r--r--lib/crypto/c_src/hmac.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/lib/crypto/c_src/hmac.c b/lib/crypto/c_src/hmac.c
index 6ddbd2c59a..ca39771cc7 100644
--- a/lib/crypto/c_src/hmac.c
+++ b/lib/crypto/c_src/hmac.c
@@ -51,35 +51,53 @@ ERL_NIF_TERM hmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
unsigned char buff[EVP_MAX_MD_SIZE];
unsigned size = 0, req_size = 0;
ERL_NIF_TERM ret;
-
- digp = get_digest_type(argv[0]);
- if (!digp ||
- !enif_inspect_iolist_as_binary(env, argv[1], &key) ||
- !enif_inspect_iolist_as_binary(env, argv[2], &data) ||
- (argc == 4 && !enif_get_uint(env, argv[3], &req_size))) {
- return enif_make_badarg(env);
+ unsigned char *outp;
+
+ if (argc != 3 && argc != 4)
+ goto bad_arg;
+
+ if ((digp = get_digest_type(argv[0])) == NULL)
+ goto bad_arg;
+ if (!enif_inspect_iolist_as_binary(env, argv[1], &key))
+ goto bad_arg;
+ if (key.size > INT_MAX)
+ goto bad_arg;
+ if (!enif_inspect_iolist_as_binary(env, argv[2], &data))
+ goto bad_arg;
+ if (argc == 4) {
+ if (!enif_get_uint(env, argv[3], &req_size))
+ goto bad_arg;
}
- if (!digp->md.p ||
- !HMAC(digp->md.p,
- key.data, key.size,
- data.data, data.size,
- buff, &size)) {
- return atom_notsup;
- }
+ if (digp->md.p == NULL)
+ goto err;
+ if (HMAC(digp->md.p,
+ key.data, (int)key.size,
+ data.data, data.size,
+ buff, &size) == NULL)
+ goto err;
+
ASSERT(0 < size && size <= EVP_MAX_MD_SIZE);
CONSUME_REDS(env, data);
if (argc == 4) {
- if (req_size <= size) {
- size = req_size;
- }
- else {
- return enif_make_badarg(env);
- }
+ if (req_size > size)
+ goto bad_arg;
+
+ size = req_size;
}
- memcpy(enif_make_new_binary(env, size, &ret), buff, size);
+
+ if ((outp = enif_make_new_binary(env, size, &ret)) == NULL)
+ goto err;
+
+ memcpy(outp, buff, size);
return ret;
+
+ bad_arg:
+ return enif_make_badarg(env);
+
+ err:
+ return atom_notsup;
}
static void hmac_context_dtor(ErlNifEnv* env, struct hmac_context *obj)