LCOV - code coverage report
Current view: top level - crypto - g_crypt_openssl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 93 98 94.9 %
Date: 2021-04-29 23:48:07 Functions: 16 17 94.1 %

          Line data    Source code
       1             : /*
       2             : *                       GPAC - Multimedia Framework C SDK
       3             : *
       4             : *                       Authors: Rodolphe Fouquet
       5             : *                       Copyright (c) Motion Spell 2016
       6             : *                                       All rights reserved
       7             : *
       8             : *  This file is part of GPAC / crypto lib sub-project
       9             : *
      10             : *  GPAC is free software; you can redistribute it and/or modify
      11             : *  it under the terms of the GNU Lesser General Public License as published by
      12             : *  the Free Software Foundation; either version 2, or (at your option)
      13             : *  any later version.
      14             : *
      15             : *  GPAC is distributed in the hope that it will be useful,
      16             : *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             : *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             : *  GNU Lesser General Public License for more details.
      19             : *
      20             : *  You should have received a copy of the GNU Lesser General Public
      21             : *  License along with this library; see the file COPYING.  If not, write to
      22             : *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             : *
      24             : */
      25             : 
      26             : #include <gpac/internal/crypt_dev.h>
      27             : 
      28             : #ifdef GPAC_HAS_SSL
      29             : #include <openssl/aes.h>
      30             : #include <openssl/modes.h>
      31             : 
      32             : #include <math.h>
      33             : 
      34             : typedef struct {
      35             :         AES_KEY enc_key, dec_key;
      36             : 
      37             :         u8 block[AES_BLOCK_SIZE];
      38             :         u8 padded_input[AES_BLOCK_SIZE]; // use only when the input length is inferior to the algo block size
      39             :         u8 previous_ciphertext[AES_BLOCK_SIZE];
      40             : } Openssl_ctx_cbc;
      41             : 
      42             : /** CBC STUFF **/
      43             : 
      44          59 : GF_Err gf_crypt_init_openssl_cbc(GF_Crypt* td, void *key, const void *iv)
      45             : {
      46          59 :         Openssl_ctx_cbc *ctx = (Openssl_ctx_cbc*)td->context;
      47          59 :         if (!ctx) {
      48          59 :                 GF_SAFEALLOC(ctx, Openssl_ctx_cbc);
      49          59 :                 if (ctx == NULL) return GF_OUT_OF_MEM;
      50          59 :                 td->context = ctx;
      51             :         }
      52             :         
      53          59 :         if (iv != NULL) {
      54          59 :                 memcpy(ctx->previous_ciphertext, iv, AES_BLOCK_SIZE);
      55             :         }
      56             :         return GF_OK;
      57             : }
      58             : 
      59          59 : void gf_crypt_deinit_openssl_cbc(GF_Crypt* td)
      60             : {
      61          59 : }
      62             : 
      63          66 : void gf_set_key_openssl_cbc(GF_Crypt* td, void *key)
      64             : {
      65          66 :         Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
      66          66 :         AES_set_encrypt_key(key, 128, &(ctx->enc_key));
      67          66 :         AES_set_decrypt_key(key, 128, &(ctx->dec_key));
      68          66 : }
      69             : 
      70       10951 : GF_Err gf_crypt_set_IV_openssl_cbc(GF_Crypt* td, const u8 *iv, u32 iv_size)
      71             : {
      72       10951 :         Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
      73       10951 :         memcpy(ctx->previous_ciphertext, iv, iv_size);
      74       10951 :         return GF_OK;
      75             : }
      76             : 
      77        2600 : GF_Err gf_crypt_get_IV_openssl_cbc(GF_Crypt* td, u8 *iv, u32 *iv_size)
      78             : {
      79        2600 :         Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
      80        2600 :         *iv_size = AES_BLOCK_SIZE;
      81        2600 :         memcpy(iv, ctx->previous_ciphertext, AES_BLOCK_SIZE);
      82        2600 :         return GF_OK;
      83             : }
      84             : 
      85       41054 : GF_Err gf_crypt_crypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len, u32 aes_crypt_type) {
      86       41054 :         Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
      87             :         u32 iteration;
      88       41054 :         AES_KEY *key = aes_crypt_type ? &ctx->enc_key : &ctx->dec_key;
      89       41054 :         u32 numberOfIterations = len / AES_BLOCK_SIZE;
      90       41054 :         if (numberOfIterations * AES_BLOCK_SIZE < len) numberOfIterations++;
      91             : 
      92      223378 :         for (iteration = 0; iteration < numberOfIterations; ++iteration) {
      93      182324 :                 if (len - iteration*AES_BLOCK_SIZE < AES_BLOCK_SIZE) {
      94           0 :                         memset(ctx->padded_input, 0, AES_BLOCK_SIZE);
      95           0 :                         memcpy(ctx->padded_input, plaintext, len - iteration*AES_BLOCK_SIZE);
      96           0 :                         AES_cbc_encrypt(plaintext + iteration*AES_BLOCK_SIZE, ctx->block, AES_BLOCK_SIZE, key, ctx->previous_ciphertext, aes_crypt_type);
      97             :                         memcpy(plaintext + iteration*AES_BLOCK_SIZE, ctx->block, len - iteration*AES_BLOCK_SIZE);
      98             :                 } else {
      99      182324 :                         AES_cbc_encrypt(plaintext + iteration*AES_BLOCK_SIZE, plaintext + iteration*AES_BLOCK_SIZE, AES_BLOCK_SIZE, key, ctx->previous_ciphertext, aes_crypt_type);
     100             :                 }
     101             :         }
     102       41054 :         return GF_OK;
     103             : }
     104             : 
     105       26648 : GF_Err gf_crypt_encrypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len)
     106             : {
     107       26648 :         return gf_crypt_crypt_openssl_cbc(td, plaintext, len, AES_ENCRYPT);
     108             : }
     109             : 
     110       14406 : GF_Err gf_crypt_decrypt_openssl_cbc(GF_Crypt* td, u8 *ciphertext, u32 len)
     111             : {
     112       14406 :         return gf_crypt_crypt_openssl_cbc(td, ciphertext, len, AES_DECRYPT);
     113             : }
     114             : 
     115             : typedef struct {
     116             :         AES_KEY key;
     117             : 
     118             :         u8 cyphered_iv[16];
     119             :         u8 iv[16];
     120             :         unsigned int c_counter_pos;
     121             : } Openssl_ctx_ctr;
     122             : 
     123             : 
     124             : /** CTR STUFF **/
     125             : 
     126         788 : void gf_set_key_openssl_ctr(GF_Crypt* td, void *key)
     127             : {
     128         788 :         Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
     129         788 :         AES_set_encrypt_key(key, 128, &(ctx->key));
     130         788 : }
     131             : 
     132       37363 : GF_Err gf_crypt_set_IV_openssl_ctr(GF_Crypt* td, const u8 *iv, u32 iv_size)
     133             : {
     134       37363 :         Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
     135             : 
     136       37363 :         ctx->c_counter_pos = ((u8*)iv)[0];
     137       37363 :         memcpy(ctx->iv, &((u8*)iv)[1], iv_size - 1);
     138       37363 :         memset(ctx->cyphered_iv, 0, 16);
     139       37363 :         return GF_OK;
     140             : }
     141             : 
     142       21117 : GF_Err gf_crypt_get_IV_openssl_ctr(GF_Crypt* td, u8 *iv, u32 *iv_size)
     143             : {
     144       21117 :         Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
     145             : 
     146       21117 :         *iv_size = AES_BLOCK_SIZE + 1;
     147             : 
     148       21117 :         ((u8 *)iv)[0] = ctx->c_counter_pos;
     149       21117 :         memcpy(&((u8 *)iv)[1], ctx->iv, AES_BLOCK_SIZE);
     150       21117 :         return GF_OK;
     151             : }
     152             : 
     153         623 : GF_Err gf_crypt_init_openssl_ctr(GF_Crypt* td, void *key, const void *iv)
     154             : {
     155         623 :         Openssl_ctx_ctr *ctx = (Openssl_ctx_ctr*)td->context;
     156         623 :         if (!ctx) {
     157         458 :                 GF_SAFEALLOC(ctx, Openssl_ctx_ctr);
     158         458 :                 if (!ctx) return GF_OUT_OF_MEM;
     159             : 
     160         458 :                 td->context = ctx;
     161             :         }
     162         623 :         ctx->c_counter_pos = 0;
     163         623 :         if (iv != NULL) {
     164         623 :                 memcpy(ctx->iv, &((u8*)iv)[0], AES_BLOCK_SIZE);
     165             :         }
     166             : 
     167             :         return GF_OK;
     168             : }
     169             : 
     170         462 : void gf_crypt_deinit_openssl_ctr(GF_Crypt* td)
     171             : {
     172         462 : }
     173             : 
     174           0 : GF_Err gf_crypt_crypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
     175             : {
     176      115812 :         Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
     177             : 
     178      115812 :         CRYPTO_ctr128_encrypt(plaintext, plaintext, len, &ctx->key, ctx->iv, ctx->cyphered_iv, &ctx->c_counter_pos, (block128_f)AES_encrypt);
     179             : 
     180           0 :         return GF_OK;
     181             : }
     182             : 
     183       60396 : GF_Err gf_crypt_encrypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
     184             : {
     185       60396 :         return gf_crypt_crypt_openssl_ctr(td, plaintext, len);
     186             : }
     187             : 
     188       55416 : GF_Err gf_crypt_decrypt_openssl_ctr(GF_Crypt* td, u8 *ciphertext, u32 len)
     189             : {
     190       55416 :         return gf_crypt_crypt_openssl_ctr(td, ciphertext, len);
     191             : }
     192             : 
     193             : 
     194         521 : GF_Err gf_crypt_open_open_openssl(GF_Crypt* td, GF_CRYPTO_MODE mode)
     195             : {
     196         521 :         td->mode = mode;
     197         521 :         switch (td->mode) {
     198          59 :         case GF_CBC:
     199          59 :                 td->_init_crypt = gf_crypt_init_openssl_cbc;
     200          59 :                 td->_deinit_crypt = gf_crypt_deinit_openssl_cbc;
     201          59 :                 td->_set_key = gf_set_key_openssl_cbc;
     202          59 :                 td->_crypt = gf_crypt_encrypt_openssl_cbc;
     203          59 :                 td->_decrypt = gf_crypt_decrypt_openssl_cbc;
     204          59 :                 td->_get_state = gf_crypt_get_IV_openssl_cbc;
     205          59 :                 td->_set_state = gf_crypt_set_IV_openssl_cbc;
     206          59 :                 break;
     207         462 :         case GF_CTR:
     208         462 :                 td->_init_crypt = gf_crypt_init_openssl_ctr;
     209         462 :                 td->_deinit_crypt = gf_crypt_deinit_openssl_ctr;
     210         462 :                 td->_set_key = gf_set_key_openssl_ctr;
     211         462 :                 td->_crypt = gf_crypt_encrypt_openssl_ctr;
     212         462 :                 td->_decrypt = gf_crypt_decrypt_openssl_ctr;
     213         462 :                 td->_get_state = gf_crypt_get_IV_openssl_ctr;
     214         462 :                 td->_set_state = gf_crypt_set_IV_openssl_ctr;
     215         462 :                 break;
     216             :         default:
     217             :                 return GF_BAD_PARAM;
     218             :                 break;
     219             :         }
     220             : 
     221         521 :         td->algo = GF_AES_128;
     222         521 :         return GF_OK;
     223             : }
     224             : 
     225             : #endif
     226             : 

Generated by: LCOV version 1.13