<p>Philip Prindeville has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18534">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">crypto: Use EVP API's instead of legacy API's<br><br>ASTERISK-30046 #close<br><br>Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com><br>Change-Id: I5c738756de75fd27ebad54be144c0ac6193f21b2<br>---<br>M channels/chan_iax2.c<br>M include/asterisk/crypto.h<br>M res/res_crypto.c<br>3 files changed, 236 insertions(+), 46 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/34/18534/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c</span><br><span>index 6d76dc5..a465649 100644</span><br><span>--- a/channels/chan_iax2.c</span><br><span>+++ b/channels/chan_iax2.c</span><br><span>@@ -6383,7 +6383,7 @@</span><br><span> {</span><br><span> int i;</span><br><span> for (i = 0; i < 60; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ecx->rd_key[i]) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ecx->raw[i]) {</span><br><span> return 0; /* stop if we encounter anything non-zero */</span><br><span> }</span><br><span> }</span><br><span>diff --git a/include/asterisk/crypto.h b/include/asterisk/crypto.h</span><br><span>index ff294ee..18cccd0 100644</span><br><span>--- a/include/asterisk/crypto.h</span><br><span>+++ b/include/asterisk/crypto.h</span><br><span>@@ -30,14 +30,15 @@</span><br><span> #include "asterisk/optional_api.h"</span><br><span> #include "asterisk/logger.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef HAVE_CRYPTO</span><br><span style="color: hsl(0, 100%, 40%);">-#include "openssl/aes.h"</span><br><span style="color: hsl(0, 100%, 40%);">-typedef AES_KEY ast_aes_encrypt_key;</span><br><span style="color: hsl(0, 100%, 40%);">-typedef AES_KEY ast_aes_decrypt_key;</span><br><span style="color: hsl(0, 100%, 40%);">-#else /* !HAVE_CRYPTO */</span><br><span style="color: hsl(0, 100%, 40%);">-typedef char ast_aes_encrypt_key;</span><br><span style="color: hsl(0, 100%, 40%);">-typedef char ast_aes_decrypt_key;</span><br><span style="color: hsl(0, 100%, 40%);">-#endif /* HAVE_CRYPTO */</span><br><span style="color: hsl(120, 100%, 40%);">+#define AST_CRYPTO_RSA_KEY_BITS 1024</span><br><span style="color: hsl(120, 100%, 40%);">+#define AST_CRYPTO_AES_BLOCKSIZE 128</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct aes_key {</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char raw[AST_CRYPTO_AES_BLOCKSIZE / 8];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct aes_key ast_aes_encrypt_key;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct aes_key ast_aes_decrypt_key;</span><br><span> </span><br><span> #define AST_CRYPTO_RSA_KEY_BITS 1024</span><br><span> #define AST_CRYPTO_AES_BLOCKSIZE 128</span><br><span>@@ -168,7 +169,7 @@</span><br><span> * \param ctx address of an aes encryption context filled in with ast_aes_set_encrypt_key</span><br><span> */</span><br><span> AST_OPTIONAL_API(void, ast_aes_encrypt,</span><br><span style="color: hsl(0, 100%, 40%);">- (const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx),</span><br><span style="color: hsl(120, 100%, 40%);">+ (const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key),</span><br><span> { ast_log(LOG_WARNING, "AES encryption disabled. Install OpenSSL.\n");return; });</span><br><span> </span><br><span> /*!</span><br><span>@@ -178,7 +179,7 @@</span><br><span> * \param ctx address of an aes encryption context filled in with ast_aes_set_decrypt_key</span><br><span> */</span><br><span> AST_OPTIONAL_API(void, ast_aes_decrypt,</span><br><span style="color: hsl(0, 100%, 40%);">- (const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx),</span><br><span style="color: hsl(120, 100%, 40%);">+ (const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key),</span><br><span> { ast_log(LOG_WARNING, "AES encryption disabled. Install OpenSSL.\n");return; });</span><br><span> </span><br><span> AST_OPTIONAL_API(int, ast_crypto_loaded, (void), { return 0; });</span><br><span>diff --git a/res/res_crypto.c b/res/res_crypto.c</span><br><span>index 5645458..b97667d 100644</span><br><span>--- a/res/res_crypto.c</span><br><span>+++ b/res/res_crypto.c</span><br><span>@@ -41,8 +41,8 @@</span><br><span> #include <openssl/err.h> /* for ERR_print_errors_fp */</span><br><span> #include <openssl/ssl.h> /* for NID_sha1, RSA */</span><br><span> #include <openssl/pem.h> /* for PEM_read_RSAPrivateKey, PEM_read_... */</span><br><span style="color: hsl(0, 100%, 40%);">-#include <openssl/rsa.h> /* for RSA_free, RSA_private_decrypt, RSA */</span><br><span> #include <openssl/sha.h> /* for SHA1 */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <openssl/evp.h> /* for EVP_PKEY, EVP_sha1(), ... */</span><br><span> </span><br><span> #include "asterisk/cli.h" /* for ast_cli, ast_cli_args, ast_cli_entry */</span><br><span> #include "asterisk/compat.h" /* for strcasecmp */</span><br><span>@@ -73,6 +73,8 @@</span><br><span> </span><br><span> #define KEY_NEEDS_PASSCODE (1 << 16)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define RSA_PKCS_OAEP_PADDING_LEN 41</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ast_key {</span><br><span> /*! Name of entity */</span><br><span> char name[80];</span><br><span>@@ -80,8 +82,8 @@</span><br><span> char fn[256];</span><br><span> /*! Key type (AST_KEY_PUB or AST_KEY_PRIV, along with flags from above) */</span><br><span> int ktype;</span><br><span style="color: hsl(0, 100%, 40%);">- /*! RSA structure (if successfully loaded) */</span><br><span style="color: hsl(0, 100%, 40%);">- RSA *rsa;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! RSA key structure (if successfully loaded) */</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY *pkey;</span><br><span> /*! Whether we should be deleted */</span><br><span> int delme;</span><br><span> /*! FD for input (or -1 if no input allowed, or -2 if we needed input) */</span><br><span>@@ -256,13 +258,13 @@</span><br><span> rewind(f);</span><br><span> /* Now load the key with the right method */</span><br><span> if (ktype == AST_KEY_PUBLIC) {</span><br><span style="color: hsl(0, 100%, 40%);">- key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);</span><br><span style="color: hsl(120, 100%, 40%);">+ PEM_read_PUBKEY(f, &key->pkey, pw_cb, key);</span><br><span> } else {</span><br><span style="color: hsl(0, 100%, 40%);">- key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);</span><br><span style="color: hsl(120, 100%, 40%);">+ PEM_read_PrivateKey(f, &key->pkey, pw_cb, key);</span><br><span> }</span><br><span> fclose(f);</span><br><span style="color: hsl(0, 100%, 40%);">- if (key->rsa) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (RSA_size(key->rsa) == 128) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (key->pkey) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (EVP_PKEY_size(key->pkey) == (AST_CRYPTO_RSA_KEY_BITS / 8)) {</span><br><span> /* Key loaded okay */</span><br><span> key->ktype &= ~KEY_NEEDS_PASSCODE;</span><br><span> ast_verb(3, "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);</span><br><span>@@ -301,6 +303,35 @@</span><br><span> return key;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_pkey_sign(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *sig, unsigned *siglen, unsigned padding)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX *ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t _siglen;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*siglen < EVP_PKEY_size(pkey))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_sign_init(ctx)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1())) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ _siglen = *siglen;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_sign(ctx, sig, &_siglen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ *siglen = _siglen;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief signs outgoing message with public key</span><br><span> * \see ast_sign_bin</span><br><span>@@ -316,82 +347,155 @@</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (siglen < EVP_PKEY_size(key->pkey)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Signature buffer too small\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Calculate digest of message */</span><br><span> SHA1((unsigned char *)msg, msglen, digest);</span><br><span> </span><br><span> /* Verify signature */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa)) != 1) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = evp_pkey_sign(key->pkey, digest, sizeof(digest), dsig, &siglen, RSA_PKCS1_PADDING)) <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "RSA Signature (key %s) failed %d\n", key->name, res);</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (siglen != 128) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (siglen != EVP_PKEY_size(key->pkey)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Unexpected signature length %u, expecting %d\n", siglen, EVP_PKEY_size(key->pkey));</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_pkey_decrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX *ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t _outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*outlen < EVP_PKEY_size(pkey))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (inlen != EVP_PKEY_size(pkey))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_decrypt_init(ctx)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ _outlen = *outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_decrypt(ctx, out, &_outlen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ res = *outlen = _outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief decrypt a message</span><br><span> * \see ast_decrypt_bin</span><br><span> */</span><br><span> int AST_OPTIONAL_API_NAME(ast_decrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- int res, pos = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned pos = 0, dstlen, blocksize;</span><br><span> </span><br><span> if (key->ktype != AST_KEY_PRIVATE) {</span><br><span> ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (srclen % 128) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ blocksize = EVP_PKEY_size(key->pkey);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (srclen % blocksize) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of %u bytes\n", blocksize);</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- while (srclen) {</span><br><span style="color: hsl(120, 100%, 40%);">+ while (srclen > 0) {</span><br><span> /* Process chunks 128 bytes at a time */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ dstlen = blocksize;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = evp_pkey_decrypt(key->pkey, src, blocksize, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) <= 0) {</span><br><span> return -1;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- pos += res;</span><br><span style="color: hsl(0, 100%, 40%);">- src += 128;</span><br><span style="color: hsl(0, 100%, 40%);">- srclen -= 128;</span><br><span style="color: hsl(0, 100%, 40%);">- dst += res;</span><br><span style="color: hsl(120, 100%, 40%);">+ pos += dstlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ src += blocksize;</span><br><span style="color: hsl(120, 100%, 40%);">+ srclen -= blocksize;</span><br><span style="color: hsl(120, 100%, 40%);">+ dst += dstlen;</span><br><span> }</span><br><span> </span><br><span> return pos;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_pkey_encrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX *ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t _outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (inlen > EVP_PKEY_size(pkey) - RSA_PKCS_OAEP_PADDING_LEN)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*outlen < EVP_PKEY_size(pkey))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_encrypt_init(ctx)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ _outlen = *outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_encrypt(ctx, out, &_outlen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ res = *outlen = _outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief encrypt a message</span><br><span> * \see ast_encrypt_bin</span><br><span> */</span><br><span> int AST_OPTIONAL_API_NAME(ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- int res, bytes, pos = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned bytes, pos = 0, dstlen, blocksize;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res;</span><br><span> </span><br><span> if (key->ktype != AST_KEY_PUBLIC) {</span><br><span> ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ blocksize = EVP_PKEY_size(key->pkey);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> while (srclen) {</span><br><span> bytes = srclen;</span><br><span style="color: hsl(0, 100%, 40%);">- if (bytes > 128 - 41) {</span><br><span style="color: hsl(0, 100%, 40%);">- bytes = 128 - 41;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bytes > blocksize - RSA_PKCS_OAEP_PADDING_LEN) {</span><br><span style="color: hsl(120, 100%, 40%);">+ bytes = blocksize - RSA_PKCS_OAEP_PADDING_LEN;</span><br><span> }</span><br><span> /* Process chunks 128-41 bytes at a time */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) != 128) {</span><br><span style="color: hsl(120, 100%, 40%);">+ dstlen = blocksize;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = evp_pkey_encrypt(key->pkey, src, bytes, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) != blocksize) {</span><br><span> ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);</span><br><span> return -1;</span><br><span> }</span><br><span> src += bytes;</span><br><span> srclen -= bytes;</span><br><span style="color: hsl(0, 100%, 40%);">- pos += res;</span><br><span style="color: hsl(0, 100%, 40%);">- dst += res;</span><br><span style="color: hsl(120, 100%, 40%);">+ pos += dstlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ dst += dstlen;</span><br><span> }</span><br><span> return pos;</span><br><span> }</span><br><span>@@ -402,6 +506,7 @@</span><br><span> */</span><br><span> int AST_OPTIONAL_API_NAME(ast_sign)(struct ast_key *key, char *msg, char *sig)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* assumes 1024 bit RSA key size */</span><br><span> unsigned char dsig[128];</span><br><span> int siglen = sizeof(dsig), res;</span><br><span> </span><br><span>@@ -413,6 +518,32 @@</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_pkey_verify(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, const unsigned char *sig, unsigned siglen, unsigned padding)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX *ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (siglen < EVP_PKEY_size(pkey))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_verify_init(ctx)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1())) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_PKEY_verify(ctx, sig, siglen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief check signature of a message</span><br><span> * \see ast_check_signature_bin</span><br><span>@@ -433,7 +564,7 @@</span><br><span> SHA1((unsigned char *)msg, msglen, digest);</span><br><span> </span><br><span> /* Verify signature */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa)) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!(res = evp_pkey_verify(key->pkey, (const unsigned char *)digest, sizeof(digest), (unsigned char *)dsig, 128, RSA_PKCS1_PADDING))) {</span><br><span> ast_debug(1, "Key failed verification: %s\n", key->name);</span><br><span> return -1;</span><br><span> }</span><br><span>@@ -475,22 +606,80 @@</span><br><span> </span><br><span> int AST_OPTIONAL_API_NAME(ast_aes_set_encrypt_key)(const unsigned char *key, ast_aes_encrypt_key *ctx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return AES_set_encrypt_key(key, 128, ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (key == NULL || ctx == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span> int AST_OPTIONAL_API_NAME(ast_aes_set_decrypt_key)(const unsigned char *key, ast_aes_decrypt_key *ctx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return AES_set_decrypt_key(key, 128, ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (key == NULL || ctx == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void AST_OPTIONAL_API_NAME(ast_aes_encrypt)(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_cipher_aes_encrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_encrypt_key *key)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return AES_encrypt(in, out, ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_CIPHER_CTX *ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res, outlen, finallen;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char final[AST_CRYPTO_AES_BLOCKSIZE / 8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_CIPHER_CTX_new()) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_EncryptInit(ctx, EVP_aes_128_ecb(), key->raw, NULL)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_EncryptUpdate(ctx, out, &outlen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* for ECB, this is a no-op */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_EncryptFinal(ctx, final, &finallen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ res = outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_CIPHER_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void AST_OPTIONAL_API_NAME(ast_aes_decrypt)(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+void AST_OPTIONAL_API_NAME(ast_aes_encrypt)(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return AES_decrypt(in, out, ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ evp_cipher_aes_encrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int evp_cipher_aes_decrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_decrypt_key *key)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_CIPHER_CTX *ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res, outlen, finallen;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char final[AST_CRYPTO_AES_BLOCKSIZE / 8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ctx = EVP_CIPHER_CTX_new()) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_DecryptInit(ctx, EVP_aes_128_ecb(), key->raw, NULL)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_DecryptUpdate(ctx, out, &outlen, in, inlen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* for ECB, this is a no-op */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((res = EVP_DecryptFinal(ctx, final, &finallen)) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ res = outlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_CIPHER_CTX_free(ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void AST_OPTIONAL_API_NAME(ast_aes_decrypt)(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ evp_cipher_aes_decrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key);</span><br><span> }</span><br><span> </span><br><span> /*!</span><br><span>@@ -533,8 +722,8 @@</span><br><span> if (key->delme) {</span><br><span> ast_debug(1, "Deleting key %s type %d\n", key->name, key->ktype);</span><br><span> AST_RWLIST_REMOVE_CURRENT(list);</span><br><span style="color: hsl(0, 100%, 40%);">- if (key->rsa) {</span><br><span style="color: hsl(0, 100%, 40%);">- RSA_free(key->rsa);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (key->pkey) {</span><br><span style="color: hsl(120, 100%, 40%);">+ EVP_PKEY_free(key->pkey);</span><br><span> }</span><br><span> ast_free(key);</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18534">change 18534</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18534"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I5c738756de75fd27ebad54be144c0ac6193f21b2 </div>
<div style="display:none"> Gerrit-Change-Number: 18534 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Philip Prindeville <philipp@redfish-solutions.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>