/* * SRT - Secure, Reliable, Transport * Copyright (c) 2019 Haivision Systems Inc. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * */ /***************************************************************************** written by Haivision Systems Inc. 2019-06-27 (jdube) GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT) *****************************************************************************/ #include "hcrypt.h" #include #include #include #include #include // Static members of cryspr::mbedtls class. static mbedtls_ctr_drbg_context crysprMbedtls_ctr_drbg; static mbedtls_entropy_context crysprMbedtls_entropy; static mbedtls_md_context_t crysprMbedtls_mdctx; typedef struct tag_crysprGnuTLS_AES_cb { CRYSPR_cb ccb; /* CRYSPR control block */ /* Add other cryptolib specific data here */ } crysprMbedtls_cb; int crysprMbedtls_Prng(unsigned char *rn, int len) { int ret = mbedtls_ctr_drbg_random( &crysprMbedtls_ctr_drbg, rn, len ); if (ret != 0) { return -1; } return 0; } int crysprMbedtls_AES_SetKey( bool bEncrypt, /* true:encrypt key, false:decrypt key*/ const unsigned char *kstr, /* key string */ size_t kstr_len, /* kstr length in bytes (16, 24, or 32 bytes, for AES128,AES192, or AES256) */ CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */ { if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) { HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) bad length\n"); return -1; } int ret; // mbedtls uses the "bits" convention (128, 192, 254), just like openssl. // kstr_len is in "bytes" convention (16, 24, 32). if (bEncrypt) { /* Encrypt key */ ret = mbedtls_aes_setkey_enc(aes_key, kstr, kstr_len*8); } else { /* Decrypt key */ ret = mbedtls_aes_setkey_dec(aes_key, kstr, kstr_len*8); } return ret == 0 ? 0 : -1; } int crysprMbedtls_AES_EcbCipher( /* AES Electronic Codebook cipher*/ bool bEncrypt, /* true:encrypt, false:decrypt */ CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */ const unsigned char *indata,/* src (clear text)*/ size_t inlen, /* length */ unsigned char *out_txt, /* dst (cipher text) */ size_t *outlen) /* dst len */ { int nblk = inlen/CRYSPR_AESBLKSZ; int nmore = inlen%CRYSPR_AESBLKSZ; int i; if (bEncrypt) { /* Encrypt packet payload, block by block, in output buffer */ for (i = 0; i < nblk; i++) { // NOTE: CRYSPR_AESBLKSZ is implicitly the ONLY POSSIBLE // size of the block. mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT, &indata[(i*CRYSPR_AESBLKSZ)], &out_txt[(i*CRYSPR_AESBLKSZ)]); } /* Encrypt last incomplete block */ if (0 < nmore) { unsigned char intxt[CRYSPR_AESBLKSZ]; memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore); memset(intxt+nmore, 0, CRYSPR_AESBLKSZ-nmore); mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT, intxt, &out_txt[(nblk*CRYSPR_AESBLKSZ)]); nblk++; } if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ; } else { /* Decrypt */ for (i=0; i