crypto: saved functions in crypto_aes.c
authorDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 2 Jun 2020 05:57:34 +0000 (07:57 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 2 Jun 2020 05:57:34 +0000 (07:57 +0200)
src/modules/crypto/crypto_aes.c

index 9573c72..777d435 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+/**
+ * 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
+ */
+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)
+{
+       int i, nrounds = 5;
+       int x;
+       unsigned char key[32], iv[32];
+
+       /*
+        * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash
+        * the supplied key material.
+        * nrounds is the number of times the we hash the material. More rounds
+        * are more secure but slower.
+        */
+       i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt,
+                       key_data, key_data_len, nrounds, key, iv);
+       if (i != 32) {
+               LM_ERR("key size is %d bits - should be 256 bits\n", i);
+               return -1;
+       }
+
+       for(x = 0; x<32; ++x)
+               LM_DBG("key: %x iv: %x \n", key[x], iv[x]);
+
+       for(x = 0; x<8; ++x)
+               LM_DBG("salt: %x\n", salt[x]);
+
+       if(e_ctx) {
+               EVP_CIPHER_CTX_init(e_ctx);
+               EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
+       }
+       if(d_ctx) {
+               EVP_CIPHER_CTX_init(d_ctx);
+               EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
+       }
+
+       return 0;
+}
+
+/*
+ * Encrypt *len bytes of data
+ * All data going in & out is considered binary (unsigned char[])
+ */
+unsigned char *crypto_aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext,
+               int *len)
+{
+       /* max ciphertext len for a n bytes of plaintext is
+        * n + AES_BLOCK_SIZE -1 bytes */
+       int c_len = *len + AES_BLOCK_SIZE - 1, f_len = 0;
+       unsigned char *ciphertext = (unsigned char *)malloc(c_len);
+
+       if(ciphertext == NULL) {
+               LM_ERR("no more system memory\n");
+               return NULL;
+       }
+       /* allows reusing of 'e' for multiple encryption cycles */
+       if(!EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL)){
+               LM_ERR("failure in EVP_EncryptInit_ex \n");
+               free(ciphertext);
+               return NULL;
+       }
+
+       /* update ciphertext, c_len is filled with the length of ciphertext
+        * generated, *len is the size of plaintext in bytes */
+       if(!EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len)){
+               LM_ERR("failure in EVP_EncryptUpdate \n");
+               free(ciphertext);
+               return NULL;
+       }
+
+       /* update ciphertext with the final remaining bytes */
+       if(!EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len)){
+               LM_ERR("failure in EVP_EncryptFinal_ex \n");
+               free(ciphertext);
+               return NULL;
+       }
+
+       *len = c_len + f_len;
+       return ciphertext;
+}
+
+/*
+ * Decrypt *len bytes of ciphertext
+ */
+unsigned char *crypto_aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext,
+               int *len)
+{
+       /* plaintext will always be equal to or lesser than length of ciphertext*/
+       int p_len = *len, f_len = 0;
+       unsigned char *plaintext = (unsigned char *)malloc(p_len);
+
+       if(plaintext==NULL) {
+               LM_ERR("no more system memory\n");
+               return NULL;
+       }
+       if(!EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL)){
+               LM_ERR("failure in EVP_DecryptInit_ex \n");
+               free(plaintext);
+               return NULL;
+       }
+
+       if(!EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len)){
+               LM_ERR("failure in EVP_DecryptUpdate\n");
+               free(plaintext);
+               return NULL;
+       }
+
+       if(!EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len)){
+               LM_ERR("failure in EVP_DecryptFinal_ex\n");
+               free(plaintext);
+               return NULL;
+       }
+
+       *len = p_len + f_len;
+       return plaintext;
+}
\ No newline at end of file