crypto: aes encrypt/decrypt based on event_route[crypto:netio]
authorDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 2 Jun 2020 08:35:18 +0000 (10:35 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 2 Jun 2020 08:35:18 +0000 (10:35 +0200)
src/modules/crypto/crypto_aes.c
src/modules/crypto/crypto_aes.h
src/modules/crypto/crypto_evcb.c
src/modules/crypto/crypto_mod.c

index 777d435..8b80d62 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../core/dprint.h"
+
+#include "crypto_aes.h"
+
+static char _crypto_salt[CRYPTO_SALT_BSIZE];
+static int _crypto_salt_set = 0;
+
+/**
+ *
+ */
+int crypto_set_salt(char *psalt)
+{
+       int i;
+       char k;
+
+       memset(_crypto_salt, 0, CRYPTO_SALT_BSIZE*sizeof(char));
+       if(psalt!=NULL) {
+               if(strlen(psalt)<8) {
+                       LM_ERR("salt parameter must be at least 8 characters\n");
+                       return -1;
+               }
+               k = 97;
+               for(i=0; i<strlen(psalt); i++) {
+                       if(i>=CRYPTO_SALT_BSIZE) break;
+                       _crypto_salt[i] = (psalt[i]*7 + k + k*(i+1))%0xff;
+                       k = _crypto_salt[i];
+               }
+               _crypto_salt_set = 1;
+       }
+       return 0;
+}
+
+/**
+ *
+ */
+char *crypto_get_salt(void)
+{
+       if(_crypto_salt_set == 0) {
+               return NULL;
+       }
+       return _crypto_salt;
+}
+
 /**
  * Create an 256 bit key and IV using the supplied key_data and salt.
  * Fills in the encryption and decryption ctx objects and returns 0 on success
index a98a950..0557e02 100644 (file)
 
 #include <openssl/evp.h>
 
+#define AES_BLOCK_SIZE 256
+#define CRYPTO_SALT_BSIZE 16
+
+int crypto_set_salt(char *psalt);
+char *crypto_get_salt(void);
+
 int crypto_aes_init(unsigned char *key_data, int key_data_len,
                unsigned char *salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx);
 
index c1abf67..8ce456f 100644 (file)
@@ -33,6 +33,7 @@
 #include "../../core/events.h"
 #include "../../core/onsend.h"
 
+#include "crypto_aes.h"
 
 #define CRYPTO_NIO_OUT (1<<0)
 #define CRYPTO_NIO_ENCRYPT (1<<1)
@@ -111,6 +112,10 @@ int crypto_exec_evroute(crypto_env_t *evenv, int rt, str *kevcb, str *rtname)
        }
        fmsg = &tmsg;
 
+       if(evenv->evp->rcv != NULL) {
+               fmsg->rcv = *evenv->evp->rcv;
+       }
+
        if(evenv->mflags & CRYPTO_NIO_OUT) {
                onsnd_info.to = &evenv->evp->dst->to;
                onsnd_info.send_sock = evenv->evp->dst->send_sock;
@@ -152,6 +157,9 @@ int crypto_nio_received(sr_event_param_t *evp)
 {
        int ret;
        crypto_env_t evenv;
+       EVP_CIPHER_CTX *de=NULL;
+       str dtext;
+       str *obuf;
 
        memset(&evenv, 0, sizeof(crypto_env_t));
 
@@ -162,10 +170,51 @@ int crypto_nio_received(sr_event_param_t *evp)
 
        LM_DBG("sent event callback - ret:%d - flags:%d\n", ret, evenv.mflags);
 
-       if(evenv.mflags & CRYPTO_NIO_DECRYPT) {
-               LM_DBG("decrypting\n");
+       if(!(evenv.mflags & CRYPTO_NIO_DECRYPT)) {
+               goto done;
+       }
+       LM_DBG("decrypting\n");
+
+       de = EVP_CIPHER_CTX_new();
+       if(de==NULL) {
+               LM_ERR("cannot get new cipher context\n");
+               return -1;
+       }
+
+       /* gen key and iv. init the cipher ctx object */
+       if (crypto_aes_init((unsigned char *)_crypto_netio_key.s, _crypto_netio_key.len,
+                               (unsigned char*)crypto_get_salt(), NULL, de)) {
+               EVP_CIPHER_CTX_free(de);
+               LM_ERR("couldn't initialize AES cipher\n");
+               return -1;
+       }
+
+       obuf = (str*)evp->data;
+       dtext.len = obuf->len;
+       dtext.s = (char *)crypto_aes_decrypt(de, (unsigned char *)obuf->s,
+                       &dtext.len);
+       if(dtext.s==NULL) {
+               EVP_CIPHER_CTX_free(de);
+               LM_ERR("AES decryption failed\n");
+               return -1;
+       }
+
+       if(dtext.len>=BUF_SIZE) {
+               LM_ERR("new buffer overflow (%d)\n", dtext.len);
+               free(dtext.s);
+               EVP_CIPHER_CTX_free(de);
+               return -1;
        }
 
+       obuf->len = dtext.len;
+       memcpy(obuf->s, dtext.s, obuf->len);
+       obuf->s[obuf->len] = '\0';
+
+       EVP_CIPHER_CTX_cleanup(de);
+       EVP_CIPHER_CTX_free(de);
+       free(dtext.s);
+
+done:
     return 0;
 }
 
@@ -176,6 +225,10 @@ int crypto_nio_sent(sr_event_param_t *evp)
 {
        int ret;
        crypto_env_t evenv;
+       EVP_CIPHER_CTX *en = NULL;
+       str etext;
+       str nbuf;
+       str *obuf;
 
        memset(&evenv, 0, sizeof(crypto_env_t));
 
@@ -187,10 +240,55 @@ int crypto_nio_sent(sr_event_param_t *evp)
 
        LM_DBG("sent event callback - ret:%d - flags:%d\n", ret, evenv.mflags);
 
-       if(evenv.mflags & CRYPTO_NIO_ENCRYPT) {
-               LM_DBG("encrypting\n");
+       if(!(evenv.mflags & CRYPTO_NIO_ENCRYPT)) {
+               goto done;
        }
 
+       LM_DBG("encrypting\n");
+       en = EVP_CIPHER_CTX_new();
+       if(en==NULL) {
+               LM_ERR("cannot get new cipher context\n");
+               return -1;
+       }
+
+       /* gen key and iv. init the cipher ctx object */
+       if (crypto_aes_init((unsigned char *)_crypto_netio_key.s, _crypto_netio_key.len,
+                               (unsigned char*)crypto_get_salt(), en, NULL)) {
+               EVP_CIPHER_CTX_free(en);
+               LM_ERR("couldn't initialize AES cipher\n");
+               return -1;
+       }
+
+       obuf = (str*)evp->data;
+
+       etext.len = obuf->len;
+       etext.s = (char *)crypto_aes_encrypt(en, (unsigned char *)obuf->s, &etext.len);
+       if(etext.s==NULL) {
+               EVP_CIPHER_CTX_free(en);
+               LM_ERR("AES encryption failed\n");
+               return -1;
+       }
+
+       nbuf.s = (char*)pkg_malloc(etext.len + 1);
+       if(nbuf.s==NULL) {
+               EVP_CIPHER_CTX_free(en);
+               PKG_MEM_ERROR;
+               free(etext.s);
+               return -1;
+       }
+       pkg_free(obuf->s);
+       nbuf.len = etext.len;
+       memcpy(nbuf.s, etext.s, nbuf.len);
+       nbuf.s[nbuf.len] = '\0';
+
+       EVP_CIPHER_CTX_cleanup(en);
+       EVP_CIPHER_CTX_free(en);
+       free(etext.s);
+
+       obuf->s = nbuf.s;
+       obuf->len = nbuf.len;
+
+done:
        return 0;
 }
 
index e737c82..c2ae77f 100644 (file)
 #include "crypto_evcb.h"
 #include "api.h"
 
-
-
-#define AES_BLOCK_SIZE 256
-
 MODULE_VERSION
 
 int crypto_aes_init(unsigned char *key_data, int key_data_len,
@@ -65,8 +61,6 @@ static int w_crypto_nio_out(sip_msg_t* msg, char* p1, char* p2);
 static int w_crypto_nio_encrypt(sip_msg_t* msg, char* p1, char* p2);
 static int w_crypto_nio_decrypt(sip_msg_t* msg, char* p1, char* p2);
 
-#define CRYPTO_SALT_BSIZE      16
-static char _crypto_salt[CRYPTO_SALT_BSIZE];
 static char *_crypto_salt_param = "k8hTm4aZ";
 
 static int _crypto_register_callid = 0;
@@ -121,23 +115,15 @@ struct module_exports exports = {
  */
 static int mod_init(void)
 {
-       int i;
-       char k;
-       memset(_crypto_salt, 0, CRYPTO_SALT_BSIZE*sizeof(char));
+
        if(_crypto_salt_param==NULL || _crypto_salt_param[0]==0) {
                _crypto_salt_param = NULL;
-       } else {
-               if(strlen(_crypto_salt_param)<8) {
-                       LM_ERR("salt parameter must be at least 8 characters\n");
-                       return -1;
-               }
-               k = 97;
-               for(i=0; i<strlen(_crypto_salt_param); i++) {
-                       if(i>=CRYPTO_SALT_BSIZE) break;
-                       _crypto_salt[i] = (_crypto_salt_param[i]*7 + k + k*(i+1))%0xff;
-                       k = _crypto_salt[i];
-               }
        }
+
+       if(crypto_set_salt(_crypto_salt_param) < 0) {
+               return -1;
+       }
+
        if(_crypto_register_callid!=0) {
                if(crypto_init_callid()<0) {
                        LM_ERR("failed to init callid callback\n");
@@ -149,6 +135,7 @@ static int mod_init(void)
                }
                LM_DBG("registered crypto callid callback\n");
        }
+
        if(_crypto_register_evcb!=0) {
                crypto_evcb_enable();
        }
@@ -195,7 +182,7 @@ static int ki_crypto_aes_encrypt_helper(sip_msg_t* msg, str *ins, str *keys,
 
        /* gen key and iv. init the cipher ctx object */
        if (crypto_aes_init((unsigned char *)keys->s, keys->len,
-                               (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), en, NULL)) {
+                               (unsigned char*)crypto_get_salt(), en, NULL)) {
                EVP_CIPHER_CTX_free(en);
                LM_ERR("couldn't initialize AES cipher\n");
                return -1;
@@ -314,7 +301,7 @@ static int ki_crypto_aes_decrypt_helper(sip_msg_t* msg, str *ins, str *keys,
 
        /* gen key and iv. init the cipher ctx object */
        if (crypto_aes_init((unsigned char *)keys->s, keys->len,
-                               (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) {
+                               (unsigned char*)crypto_get_salt(), NULL, de)) {
                EVP_CIPHER_CTX_free(de);
                LM_ERR("couldn't initialize AES cipher\n");
                return -1;