diff options
-rw-r--r-- | lib/crypto/c_src/Makefile.in | 1 | ||||
-rw-r--r-- | lib/crypto/c_src/cmac.c | 73 | ||||
-rw-r--r-- | lib/crypto/c_src/cmac.h | 34 | ||||
-rw-r--r-- | lib/crypto/c_src/hmac.c | 50 | ||||
-rw-r--r-- | lib/crypto/c_src/hmac.h | 4 | ||||
-rw-r--r-- | lib/crypto/c_src/mac.c | 107 |
6 files changed, 164 insertions, 105 deletions
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 6e173f8619..2512013ed6 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -79,6 +79,7 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \ $(OBJDIR)/atoms$(TYPEMARKER).o \ $(OBJDIR)/bn$(TYPEMARKER).o \ $(OBJDIR)/cipher$(TYPEMARKER).o \ + $(OBJDIR)/cmac$(TYPEMARKER).o \ $(OBJDIR)/dh$(TYPEMARKER).o \ $(OBJDIR)/digest$(TYPEMARKER).o \ $(OBJDIR)/dss$(TYPEMARKER).o \ diff --git a/lib/crypto/c_src/cmac.c b/lib/crypto/c_src/cmac.c new file mode 100644 index 0000000000..a1564f6661 --- /dev/null +++ b/lib/crypto/c_src/cmac.c @@ -0,0 +1,73 @@ +/* + * %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 "common.h" + +/***************************************************************** + * + * This file has functions for compatibility with cryptolibs + * lacking the EVP_Digest API. + * + * See mac.c for the implementation using the EVP interface. + * + ****************************************************************/ + +#if defined(HAVE_CMAC) && !defined(HAVE_EVP_PKEY_new_CMAC_key) + +#include "cmac.h" + +int cmac_low_level(ErlNifEnv* env, + ErlNifBinary key_bin, const EVP_CIPHER* cipher, ErlNifBinary text, + ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term) +{ + CMAC_CTX *ctx = NULL; + size_t size; + + if ((ctx = CMAC_CTX_new()) == NULL) + goto local_err; + + if (!CMAC_Init(ctx, key_bin.data, key_bin.size, cipher, NULL)) + goto local_err; + + if (!CMAC_Update(ctx, text.data, text.size)) + goto local_err; + + if ((size = (size_t)EVP_CIPHER_block_size(cipher)) < 0) + goto local_err; + + if (!enif_alloc_binary(size, ret_bin)) + goto local_err; + *ret_bin_alloc = 1; + + if (!CMAC_Final(ctx, ret_bin->data, &ret_bin->size)) + goto local_err; + + CMAC_CTX_free(ctx); + return 1; + + local_err: + if (ctx) + CMAC_CTX_free(ctx); + + *return_term = EXCP_ERROR(env,"Compat cmac"); + return 0; +} + +#endif diff --git a/lib/crypto/c_src/cmac.h b/lib/crypto/c_src/cmac.h new file mode 100644 index 0000000000..04c742b2dc --- /dev/null +++ b/lib/crypto/c_src/cmac.h @@ -0,0 +1,34 @@ +/* + * %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_CMAC_H__ +#define E_CMAC_H__ 1 + +#include "common.h" + +#if defined(HAVE_CMAC) && !defined(HAVE_EVP_PKEY_new_CMAC_key) + +int cmac_low_level(ErlNifEnv* env, + ErlNifBinary key_bin, const EVP_CIPHER* cipher, ErlNifBinary text, + ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term); + +#endif + +#endif /* E_CMAC_H__ */ diff --git a/lib/crypto/c_src/hmac.c b/lib/crypto/c_src/hmac.c index 1a4f96e1d5..5e2c68bfee 100644 --- a/lib/crypto/c_src/hmac.c +++ b/lib/crypto/c_src/hmac.c @@ -18,6 +18,16 @@ * %CopyrightEnd% */ + +/***************************************************************** + * + * This file has functions for compatibility with cryptolibs + * lacking the EVP_Digest API. + * + * See mac.c for the implementation using the EVP interface. + * + ****************************************************************/ + #ifndef HAS_EVP_PKEY_CTX #include "hmac.h" @@ -215,4 +225,44 @@ ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return ret; } + + +int hmac_low_level(ErlNifEnv* env, const EVP_MD *md, + ErlNifBinary key_bin, ErlNifBinary text, + ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term) +{ + unsigned int size_int; + size_t size; + + /* Find the needed space */ + if (HMAC(md, + key_bin.data, (int)key_bin.size, + text.data, text.size, + NULL, &size_int) == NULL) + { + *return_term = EXCP_ERROR(env, "Get HMAC size failed"); + return 0; + } + + size = (size_t)size_int; /* Otherwise "size" is unused in 0.9.8.... */ + if (!enif_alloc_binary(size, ret_bin)) + { + *return_term = EXCP_ERROR(env, "Alloc binary"); + return 0; + } + *ret_bin_alloc = 1; + + /* And do the real HMAC calc */ + if (HMAC(md, + key_bin.data, (int)key_bin.size, + text.data, text.size, + ret_bin->data, &size_int) == NULL) + { + *return_term = EXCP_ERROR(env, "HMAC sign failed"); + return 0; + } + + return 1; +} + #endif diff --git a/lib/crypto/c_src/hmac.h b/lib/crypto/c_src/hmac.h index 5df837a874..f5805e13e5 100644 --- a/lib/crypto/c_src/hmac.h +++ b/lib/crypto/c_src/hmac.h @@ -30,6 +30,10 @@ int init_hmac_ctx(ErlNifEnv *env); ERL_NIF_TERM hmac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM hmac_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + +int hmac_low_level(ErlNifEnv* env, const EVP_MD *md, + ErlNifBinary key_bin, ErlNifBinary text, + ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term); #endif #endif /* E_HMAC_H__ */ diff --git a/lib/crypto/c_src/mac.c b/lib/crypto/c_src/mac.c index 0e7f9a5651..1995d67c2c 100644 --- a/lib/crypto/c_src/mac.c +++ b/lib/crypto/c_src/mac.c @@ -21,6 +21,7 @@ #include "common.h" #include "cipher.h" #include "digest.h" +#include "cmac.h" #include "hmac.h" #include "mac.h" @@ -85,18 +86,6 @@ struct mac_type_t* get_mac_type(ERL_NIF_TERM type); ERL_NIF_TERM mac_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -#if defined(HAVE_CMAC) && !defined(HAVE_EVP_PKEY_new_CMAC_key) -int cmac_low_level(ErlNifEnv* env, - ErlNifBinary key_bin, const struct cipher_type_t *cipherp, ErlNifBinary text, - ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term); -#endif - -#if !defined(HAS_EVP_PKEY_CTX) -int hmac_low_level(ErlNifEnv* env, const EVP_MD *md, - ErlNifBinary key_bin, ErlNifBinary text, - ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term); -#endif - ERL_NIF_TERM mac_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -290,11 +279,10 @@ ERL_NIF_TERM mac_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) # ifdef HAVE_EVP_PKEY_new_CMAC_key pkey = EVP_PKEY_new_CMAC_key(/*engine*/ NULL, key_bin.data, key_bin.size, cipherp->cipher.p); # else - if (!cmac_low_level(env, key_bin, cipherp, text, &ret_bin, &ret_bin_alloc, &return_term)) + if (!cmac_low_level(env, key_bin, cipherp->cipher.p, text, &ret_bin, &ret_bin_alloc, &return_term)) goto err; else goto success; - /* End of CMAC compatibility functions */ # endif } break; @@ -417,97 +405,6 @@ ERL_NIF_TERM mac_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) } -/***************************************************************** - ***************************************************************** - - Low level compatibility functions for HMAC and CMAC - - ***************************************************************** - ****************************************************************/ - -#if defined(HAVE_CMAC) && !defined(HAVE_EVP_PKEY_new_CMAC_key) - -int cmac_low_level(ErlNifEnv* env, - ErlNifBinary key_bin, const struct cipher_type_t *cipherp, ErlNifBinary text, - ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term) -{ - CMAC_CTX *ctx = NULL; - size_t size; - - if ((ctx = CMAC_CTX_new()) == NULL) - goto local_err; - - if (!CMAC_Init(ctx, key_bin.data, key_bin.size, cipherp->cipher.p, NULL)) - goto local_err; - - if (!CMAC_Update(ctx, text.data, text.size)) - goto local_err; - - if ((size = (size_t)EVP_CIPHER_block_size(cipherp->cipher.p)) < 0) - goto local_err; - - if (!enif_alloc_binary(size, ret_bin)) - goto local_err; - *ret_bin_alloc = 1; - - if (!CMAC_Final(ctx, ret_bin->data, &ret_bin->size)) - goto local_err; - - CMAC_CTX_free(ctx); - return 1; - - local_err: - if (ctx) - CMAC_CTX_free(ctx); - - *return_term = EXCP_ERROR(env,"Compat cmac"); - return 0; -} - -#endif - - -#if !defined(HAS_EVP_PKEY_CTX) -int hmac_low_level(ErlNifEnv* env, const EVP_MD *md, - ErlNifBinary key_bin, ErlNifBinary text, - ErlNifBinary *ret_bin, int *ret_bin_alloc, ERL_NIF_TERM *return_term) -{ - unsigned int size_int; - size_t size; - - /* Find the needed space */ - if (HMAC(md, - key_bin.data, (int)key_bin.size, - text.data, text.size, - NULL, &size_int) == NULL) - { - *return_term = EXCP_ERROR(env, "Get HMAC size failed"); - return 0; - } - - size = (size_t)size_int; /* Otherwise "size" is unused in 0.9.8.... */ - if (!enif_alloc_binary(size, ret_bin)) - { - *return_term = EXCP_ERROR(env, "Alloc binary"); - return 0; - } - *ret_bin_alloc = 1; - - /* And do the real HMAC calc */ - if (HMAC(md, - key_bin.data, (int)key_bin.size, - text.data, text.size, - ret_bin->data, &size_int) == NULL) - { - *return_term = EXCP_ERROR(env, "HMAC sign failed"); - return 0; - } - - return 1; -} -#endif - - /******************************************************************* * * Mac ctx |