blob: 8549568e25dc7827fd0d2079bfa0b965d36f2646 [file] [edit]
/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2018-2022
* All rights reserved
*
* This file is part of GPAC / crypto lib sub-project
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <gpac/internal/crypt_dev.h>
#ifndef GPAC_HAS_SSL
#include "tiny_aes.h"
#include <math.h>
/** CBC mode **/
GF_Err gf_crypt_init_tinyaes_cbc(GF_Crypt* td, void *key, const void *iv)
{
struct AES_ctx *ctx = (struct AES_ctx *)td->context;
if (!ctx) {
GF_SAFEALLOC(ctx, struct AES_ctx);
if (ctx == NULL) return GF_OUT_OF_MEM;
td->context = ctx;
}
if (iv != NULL) {
AES_init_ctx_iv(ctx, key, iv);
} else {
AES_init_ctx(ctx, key);
}
return GF_OK;
}
void gf_crypt_deinit_tinyaes_cbc(GF_Crypt* td)
{
}
void gf_set_key_tinyaes_cbc(GF_Crypt* td, void *key)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_init_ctx(ctx, key);
}
GF_Err gf_crypt_set_IV_tinyaes_cbc(GF_Crypt* td, const u8 *iv, u32 iv_size)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
if (iv_size>AES_BLOCKLEN) return GF_BAD_PARAM;
AES_ctx_set_iv(ctx, iv);
return GF_OK;
}
GF_Err gf_crypt_get_IV_tinyaes_cbc(GF_Crypt* td, u8 *iv, u32 *iv_size)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_ctx_get_iv(ctx, iv);
*iv_size = AES_BLOCKLEN;
return GF_OK;
}
GF_Err gf_crypt_encrypt_tinyaes_cbc(GF_Crypt* td, u8 *plaintext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_CBC_encrypt_buffer(ctx, plaintext, len);
return GF_OK;
}
GF_Err gf_crypt_decrypt_tinyaes_cbc(GF_Crypt* td, u8 *ciphertext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
if (len<AES_BLOCKLEN) return GF_OK;
while (len % AES_BLOCKLEN)
len--;
AES_CBC_decrypt_buffer(ctx, ciphertext, len);
return GF_OK;
}
/** CTR mode **/
void gf_set_key_tinyaes_ctr(GF_Crypt* td, void *key)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_init_ctx(ctx, key);
}
GF_Err gf_crypt_set_IV_tinyaes_ctr(GF_Crypt* td, const u8 *iv, u32 iv_size)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
if (iv_size>AES_BLOCKLEN) {
ctx->counter_pos = iv[0];
AES_ctx_set_iv(ctx, &((u8*)iv)[1]);
} else {
AES_ctx_set_iv(ctx, iv);
}
return GF_OK;
}
GF_Err gf_crypt_get_IV_tinyaes_ctr(GF_Crypt* td, u8 *iv, u32 *iv_size)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
*iv_size = AES_BLOCKLEN + 1;
iv[0] = ctx->counter_pos;
AES_ctx_get_iv(ctx, iv + 1);
return GF_OK;
}
GF_Err gf_crypt_init_tinyaes_ctr(GF_Crypt* td, void *key, const void *iv)
{
struct AES_ctx* ctx = (struct AES_ctx* ) td->context;
if (!ctx) {
GF_SAFEALLOC(ctx, struct AES_ctx);
if (ctx == NULL) return GF_OUT_OF_MEM;
td->context = ctx;
}
/* For ctr */
if (iv) {
AES_init_ctx_iv(ctx, key, iv);
} else {
AES_init_ctx(ctx, key);
}
return GF_OK;
}
void gf_crypt_deinit_tinyaes_ctr(GF_Crypt* td)
{
}
GF_Err gf_crypt_encrypt_tinyaes_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_CTR_xcrypt_buffer(ctx, plaintext, len);
return GF_OK;
}
GF_Err gf_crypt_decrypt_tinyaes_ctr(GF_Crypt* td, u8 *ciphertext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_CTR_xcrypt_buffer(ctx, ciphertext, len);
return GF_OK;
}
/** ECB mode **/
GF_Err gf_crypt_init_tinyaes_ecb(GF_Crypt* td, void *key, const void *iv)
{
struct AES_ctx *ctx = (struct AES_ctx *)td->context;
if (!ctx) {
GF_SAFEALLOC(ctx, struct AES_ctx);
if (ctx == NULL) return GF_OUT_OF_MEM;
td->context = ctx;
}
AES_init_ctx(ctx, key);
return GF_OK;
}
void gf_crypt_deinit_tinyaes_ecb(GF_Crypt* td)
{
}
void gf_set_key_tinyaes_ecb(GF_Crypt* td, void *key)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
AES_init_ctx(ctx, key);
}
GF_Err gf_crypt_set_IV_tinyaes_ecb(GF_Crypt* td, const u8 *iv, u32 iv_size)
{
return GF_OK;
}
GF_Err gf_crypt_get_IV_tinyaes_ecb(GF_Crypt* td, u8 *iv, u32 *iv_size)
{
*iv_size = AES_BLOCKLEN;
memset(iv, 0, AES_BLOCKLEN);
return GF_OK;
}
GF_Err gf_crypt_encrypt_tinyaes_ecb(GF_Crypt* td, u8 *plaintext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
if (len % AES_BLOCKLEN) return GF_BAD_PARAM;
while (len) {
AES_ECB_encrypt(ctx, plaintext);
plaintext += AES_BLOCKLEN;
len -= AES_BLOCKLEN;
}
return GF_OK;
}
GF_Err gf_crypt_decrypt_tinyaes_ecb(GF_Crypt* td, u8 *ciphertext, u32 len)
{
struct AES_ctx* ctx = (struct AES_ctx *)td->context;
if (len % AES_BLOCKLEN) return GF_BAD_PARAM;
while (len) {
AES_ECB_decrypt(ctx, ciphertext);
ciphertext += AES_BLOCKLEN;
len -= AES_BLOCKLEN;
}
return GF_OK;
}
GF_Err gf_crypt_open_open_tinyaes(GF_Crypt* td, GF_CRYPTO_MODE mode)
{
td->mode = mode;
switch (td->mode) {
case GF_CBC:
td->_init_crypt = gf_crypt_init_tinyaes_cbc;
td->_deinit_crypt = gf_crypt_deinit_tinyaes_cbc;
td->_set_key = gf_set_key_tinyaes_cbc;
td->_crypt = gf_crypt_encrypt_tinyaes_cbc;
td->_decrypt = gf_crypt_decrypt_tinyaes_cbc;
td->_get_state = gf_crypt_get_IV_tinyaes_cbc;
td->_set_state = gf_crypt_set_IV_tinyaes_cbc;
break;
case GF_CTR:
td->_init_crypt = gf_crypt_init_tinyaes_ctr;
td->_deinit_crypt = gf_crypt_deinit_tinyaes_ctr;
td->_set_key = gf_set_key_tinyaes_ctr;
td->_crypt = gf_crypt_encrypt_tinyaes_ctr;
td->_decrypt = gf_crypt_decrypt_tinyaes_ctr;
td->_get_state = gf_crypt_get_IV_tinyaes_ctr;
td->_set_state = gf_crypt_set_IV_tinyaes_ctr;
break;
case GF_ECB:
td->_init_crypt = gf_crypt_init_tinyaes_ecb;
td->_deinit_crypt = gf_crypt_deinit_tinyaes_ecb;
td->_set_key = gf_set_key_tinyaes_ecb;
td->_crypt = gf_crypt_encrypt_tinyaes_ecb;
td->_decrypt = gf_crypt_decrypt_tinyaes_ecb;
td->_get_state = gf_crypt_get_IV_tinyaes_ecb;
td->_set_state = gf_crypt_set_IV_tinyaes_ecb;
break;
default:
return GF_BAD_PARAM;
break;
}
td->algo = GF_AES_128;
return GF_OK;
}
#endif