123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- /*
- * 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-28 (jdube)
- CRYSPR/4SRT Initial implementation.
- *****************************************************************************/
- #include "hcrypt.h"
- #include "cryspr.h"
- #include <stdlib.h>
- #include <string.h>
- int crysprStub_Prng(unsigned char *rn, int len)
- {
- (void)rn;
- (void)len;
- return(0);
- }
- int crysprStub_AES_SetKey(
- int cipher_type, /* One of HCRYPT_CTX_MODE_[CLRTXT|AESECB|AESCTR|AESGDM] */
- bool bEncrypt, /* true Enxcrypt key, false: decrypt */
- const unsigned char *kstr, /* key sttring*/
- size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
- CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
- {
- (void)cipher_type;
- (void)bEncrypt;
- (void)kstr;
- (void)kstr_len;
- (void)aes_key;
- return(0);
- }
- int crysprStub_AES_EcbCipher(
- bool bEncrypt, /* true:encrypt, false:decrypt */
- CRYSPR_AESCTX *aes_key, /* 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 */
- {
- (void)bEncrypt;
- (void)aes_key;
- (void)indata;
- (void)inlen;
- (void)out_txt;
- (void)outlen;
- return -1;
- }
- int crysprStub_AES_CtrCipher(
- bool bEncrypt, /* true:encrypt, false:decrypt */
- CRYSPR_AESCTX *aes_key, /* AES context */
- unsigned char *iv, /* iv */
- const unsigned char *indata,/* src */
- size_t inlen, /* length */
- unsigned char *out_txt) /* dest */
- {
- (void)bEncrypt;
- (void)aes_key;
- (void)iv;
- (void)indata;
- (void)inlen;
- (void)out_txt;
- return(-1);
- }
- int crysprStub_AES_GCMCipher(
- bool bEncrypt, /* true:encrypt, false:decrypt */
- CRYSPR_AESCTX *aes_key, /* AES context */
- unsigned char *iv, /* iv */
- const unsigned char *aad, /* associated data */
- size_t aadlen,
- const unsigned char * indata,
- size_t inlen,
- unsigned char *out_txt,
- unsigned char* out_tag)
- {
- (void)bEncrypt;
- (void)aes_key;
- (void)iv;
- (void)aad;
- (void)aadlen;
- (void)indata;
- (void)inlen;
- (void)out_txt;
- (void)out_tag;
- return(-1);
- }
- unsigned char *crysprStub_SHA1_MsgDigest(
- const unsigned char *m, /* in: message */
- size_t m_len, /* message length */
- unsigned char *md) /* out: message digest buffer *160 bytes */
- {
- (void)m;
- (void)m_len;
- (void)md;
- return(NULL);//return md;
- }
- /*
- * Password-based Key Derivation Function
- */
- int crysprStub_KmPbkdf2(
- CRYSPR_cb *cryspr_cb,
- char *passwd, /* passphrase */
- size_t passwd_len, /* passphrase len */
- unsigned char *salt, /* salt */
- size_t salt_len, /* salt_len */
- int itr, /* iterations */
- size_t key_len, /* key_len */
- unsigned char *out) /* derived key */
- {
- (void)cryspr_cb;
- (void)passwd;
- (void)passwd_len;
- (void)salt;
- (void)salt_len;
- (void)itr;
- (void)key_len;
- (void)out;
- /* >>Todo:
- * develop PBKDF2 using SHA1 primitive cryspr_cb->cryspr->sha1_msg_digest() for cryptolibs not providing it
- */
- return(-1);
- }
- static int crysprFallback_KmSetKey(CRYSPR_cb *cryspr_cb, bool bWrap, const unsigned char *kek, size_t kek_len)
- {
- CRYSPR_AESCTX *aes_kek = CRYSPR_GETKEK(cryspr_cb);
- if (cryspr_cb->cryspr->aes_set_key(HCRYPT_CTX_MODE_AESECB, bWrap, kek, kek_len, aes_kek)) {
- HCRYPT_LOG(LOG_ERR, "aes_set_%s_key(kek) failed\n", bWrap? "encrypt": "decrypt");
- return(-1);
- }
- return(0);
- }
- /*
- * AES_wrap_key()/AES_unwrap_key() introduced in openssl 0.9.8h
- * Here is an implementation using AES native API for cryspr not providing it.
- */
- static const unsigned char default_iv[] = {
- 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
- };
- int crysprFallback_AES_WrapKey(CRYSPR_cb *cryspr_cb,
- unsigned char *out,
- const unsigned char *in,
- unsigned int inlen)
- {
- unsigned char *A, B[16], *R;
- const unsigned char *iv = default_iv;
- unsigned int i, j, t;
- if ((inlen & 0x7) || (inlen < 8))
- return -1;
- A = B;
- t = 1;
- memcpy(out + 8, in, inlen);
- memcpy(A, iv, 8);
- for (j = 0; j < 6; j++)
- {
- R = out + 8;
- for (i = 0; i < inlen; i += 8, t++, R += 8)
- {
- memcpy(B + 8, R, 8);
- {
- size_t outlen = 16;
- CRYSPR_AESCTX *aes_kek = CRYSPR_GETKEK(cryspr_cb);
- cryspr_cb->cryspr->aes_ecb_cipher(true, aes_kek, B, 16, B, &outlen);
- }
- A[7] ^= (unsigned char)(t & 0xff);
- if (t > 0xff)
- {
- A[6] ^= (unsigned char)((t >> 8) & 0xff);
- A[5] ^= (unsigned char)((t >> 16) & 0xff);
- A[4] ^= (unsigned char)((t >> 24) & 0xff);
- }
- memcpy(R, B + 8, 8);
- }
- }
- memcpy(out, A, 8);
- return 0;
- }
- int crysprFallback_AES_UnwrapKey(CRYSPR_cb *cryspr_cb,
- unsigned char *out,
- const unsigned char *in,
- unsigned int inlen)
- {
- unsigned char *A, B[16], *R;
- const unsigned char *iv = default_iv;
- unsigned int i, j, t;
- inlen -= 8;
- if (inlen & 0x7)
- return -1;
- if (inlen < 8)
- return -1;
- A = B;
- t = 6 * (inlen >> 3);
- memcpy(A, in, 8);
- memcpy(out, in + 8, inlen);
- for (j = 0; j < 6; j++)
- {
- R = out + inlen - 8;
- for (i = 0; i < inlen; i += 8, t--, R -= 8)
- {
- A[7] ^= (unsigned char)(t & 0xff);
- if (t > 0xff)
- {
- A[6] ^= (unsigned char)((t >> 8) & 0xff);
- A[5] ^= (unsigned char)((t >> 16) & 0xff);
- A[4] ^= (unsigned char)((t >> 24) & 0xff);
- }
- memcpy(B + 8, R, 8);
- {
- size_t outlen = 16;
- CRYSPR_AESCTX *aes_kek = CRYSPR_GETKEK(cryspr_cb);
- cryspr_cb->cryspr->aes_ecb_cipher(false, aes_kek, B, 16, B, &outlen);
- }
- memcpy(R, B + 8, 8);
- }
- }
- if (memcmp(A, iv, 8))
- {
- memset(out, 0, inlen);
- return -1;
- }
- return 0;
- }
- static unsigned char *_crysprFallback_GetOutbuf(CRYSPR_cb *cryspr_cb, size_t pfx_len, size_t out_len)
- {
- unsigned char *out_buf;
- if ((pfx_len + out_len) > (cryspr_cb->outbuf_siz - cryspr_cb->outbuf_ofs)) {
- /* Not enough room left, circle buffers */
- cryspr_cb->outbuf_ofs = 0;
- }
- out_buf = &cryspr_cb->outbuf[cryspr_cb->outbuf_ofs];
- cryspr_cb->outbuf_ofs += (pfx_len + out_len);
- return(out_buf);
- }
- CRYSPR_cb *crysprHelper_Open(CRYSPR_methods *cryspr, size_t cb_len, size_t max_len)
- {
- CRYSPR_cb *cryspr_cb;
- unsigned char *membuf;
- size_t memsiz, padded_len = hcryptMsg_PaddedLen(max_len, 128/8);
- if(cb_len < sizeof(*cryspr_cb)) {
- HCRYPT_LOG(LOG_ERR, "crysprHelper_Open() cb_len too small (%zd < %zd)n",
- cb_len, sizeof(*cryspr_cb));
- return(NULL);
- }
- memsiz = cb_len + (CRYSPR_OUTMSGMAX * padded_len);
- #if !CRYSPR_HAS_AESCTR
- memsiz += HCRYPT_CTR_STREAM_SZ;
- #endif /* !CRYSPR_HAS_AESCTR */
- cryspr_cb = calloc(1, memsiz);
- if (NULL == cryspr_cb) {
- HCRYPT_LOG(LOG_ERR, "malloc(%zd) failed\n", memsiz);
- return(NULL);
- }
- membuf = (unsigned char *)cryspr_cb;
- membuf += sizeof(*cryspr_cb);
- /*reserve cryspr's private data that caller will initialize */
- membuf += (cb_len-sizeof(CRYSPR_cb));
- #if !CRYSPR_HAS_AESCTR
- cryspr_cb->ctr_stream = membuf;
- membuf += HCRYPT_CTR_STREAM_SZ;
- cryspr_cb->ctr_stream_siz = HCRYPT_CTR_STREAM_SZ;
- cryspr_cb->ctr_stream_len = 0;
- #endif /* !CRYSPR_HAS_AESCTR */
- cryspr_cb->outbuf = membuf;
- cryspr_cb->outbuf_siz = CRYSPR_OUTMSGMAX * padded_len;
- cryspr_cb->outbuf_ofs = 0;
- // membuf += cryspr_cb->outbuf_siz;
- cryspr_cb->cryspr=(CRYSPR_methods *)cryspr;
- return(cryspr_cb);
- }
- int crysprHelper_Close(CRYSPR_cb *cryspr_cb)
- {
- free(cryspr_cb);
- return(0);
- }
- static CRYSPR_cb *crysprFallback_Open(CRYSPR_methods *cryspr, size_t max_len)
- {
- CRYSPR_cb *cryspr_cb;
- cryspr_cb = crysprHelper_Open(cryspr, sizeof(CRYSPR_cb), max_len);
- return(cryspr_cb);
- }
- static int crysprFallback_Close(CRYSPR_cb *cryspr_cb)
- {
- return(crysprHelper_Close(cryspr_cb));
- }
- static int crysprFallback_MsSetKey(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, const unsigned char *key, size_t key_len)
- {
- CRYSPR_AESCTX *aes_sek = CRYSPR_GETSEK(cryspr_cb, hcryptCtx_GetKeyIndex(ctx)); /* Ctx tells if it's for odd or even key */
- if (ctx->mode == HCRYPT_CTX_MODE_AESGCM) { /* AES GCM mode */
- if (cryspr_cb->cryspr->aes_set_key(HCRYPT_CTX_MODE_AESGCM, (ctx->flags & HCRYPT_CTX_F_ENCRYPT) != 0, key, key_len, aes_sek)) {
- HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_encrypt_key(sek) failed\n");
- return(-1);
- }
- } else if ((ctx->flags & HCRYPT_CTX_F_ENCRYPT) /* Encrypt key */
- || (ctx->mode == HCRYPT_CTX_MODE_AESCTR)) { /* CTR mode decrypts using encryption methods */
- if (cryspr_cb->cryspr->aes_set_key(HCRYPT_CTX_MODE_AESCTR, true, key, key_len, aes_sek)) {
- HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_encrypt_key(sek) failed\n");
- return(-1);
- }
- } else { /* Decrypt key */
- if (cryspr_cb->cryspr->aes_set_key(HCRYPT_CTX_MODE_AESCTR, false, key, key_len, aes_sek)) {
- HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_decrypt_key(sek) failed\n");
- return(-1);
- }
- }
- return(0);
- }
- #if !CRYSPR_HAS_AESCTR
- static int _crysprFallback_AES_SetCtrStream(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, size_t len, unsigned char *iv)
- {
- /* Counter stream:
- * 0 1 2 3 4 5 nblk
- * +---+---+---+---+---+---+---+---+
- * |blk|blk|blk|blk|blk|blk|...|blk|
- * +---+---+---+---+---+---+---+---+
- */
- /* IV (128-bit):
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | 0s | pki | ctr |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * XOR
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | nonce +
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * pki (32-bit): packet index
- * ctr (16-bit): block counter
- * nonce (112-bit): number used once (salt)
- */
- unsigned char ctr[HCRYPT_CTR_BLK_SZ];
- unsigned nblk;
- ASSERT(NULL != cryspr_cb);
- ASSERT(NULL != ctx);
- memcpy(ctr, iv, HCRYPT_CTR_BLK_SZ);
- nblk = (len + (HCRYPT_CTR_BLK_SZ-1))/HCRYPT_CTR_BLK_SZ;
- if ((nblk * HCRYPT_CTR_BLK_SZ) <= cryspr_cb->ctr_stream_siz) {
- unsigned blk;
- unsigned char *csp = &cryspr_cb->ctr_stream[0];
- for(blk = 0; blk < nblk; blk++) {
- memcpy(csp, ctr, HCRYPT_CTR_BLK_SZ);
- csp += HCRYPT_CTR_BLK_SZ;
- if (0 == ++(ctr[HCRYPT_CTR_BLK_SZ-1])) ++(ctr[HCRYPT_CTR_BLK_SZ-2]);
- }
- cryspr_cb->ctr_stream_len = nblk * HCRYPT_CTR_BLK_SZ;
- } else {
- HCRYPT_LOG(LOG_ERR, "packet too long(%zd)\n", len);
- return(-1);
- }
- return(0);
- }
- #endif
- static int crysprFallback_MsEncrypt(
- CRYSPR_cb *cryspr_cb,
- hcrypt_Ctx *ctx,
- hcrypt_DataDesc *in_data, int nbin ATR_UNUSED,
- void *out_p[], size_t out_len_p[], int *nbout_p)
- {
- unsigned char *out_msg;
- size_t out_len = 0; //payload size
- int pfx_len;
- ASSERT(NULL != ctx);
- ASSERT(NULL != cryspr_cb);
- ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
- /*
- * Get message prefix length
- * to reserve room for unencrypted message header in output buffer
- */
- pfx_len = ctx->msg_info->pfx_len;
- /* Extra 16 bytes are needed for an authentication tag in GCM. */
- const int aux_len = (ctx->mode == HCRYPT_CTX_MODE_AESGCM) ? HAICRYPT_AUTHTAG_MAX : 0;
- /* Auth tag produced by AES GCM. */
- unsigned char tag[HAICRYPT_AUTHTAG_MAX];
- /*
- * Get buffer room from the internal circular output buffer.
- * Reserve additional 16 bytes for auth tag in AES GCM mode when needed.
- */
- out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, in_data[0].len + aux_len);
- if (NULL == out_msg) {
- /* input data too big */
- return(-1);
- }
- switch(ctx->mode) {
- case HCRYPT_CTX_MODE_AESCTR: /* Counter mode */
- case HCRYPT_CTX_MODE_AESGCM:
- {
- /* Get current key (odd|even) from context */
- CRYSPR_AESCTX *aes_key = CRYSPR_GETSEK(cryspr_cb, hcryptCtx_GetKeyIndex(ctx)); /* Ctx tells if it's for odd or even key */
- unsigned char iv[CRYSPR_AESBLKSZ];
- /* Get input packet index (in network order) */
- hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
- /*
- * Compute the Initial Vector
- * IV (128-bit):
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | 0s | pki | ctr |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * XOR
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | nonce +
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * pki (32-bit): packet index
- * ctr (16-bit): block counter
- * nonce (112-bit): number used once (salt)
- */
- hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
- if (ctx->mode == HCRYPT_CTX_MODE_AESGCM)
- {
- const int iret = cryspr_cb->cryspr->aes_gcm_cipher(true, aes_key, iv, in_data[0].pfx, pfx_len, in_data[0].payload, in_data[0].len,
- &out_msg[pfx_len], tag);
- if (iret) {
- return(iret);
- }
- }
- else {
- #if CRYSPR_HAS_AESCTR
- cryspr_cb->cryspr->aes_ctr_cipher(true, aes_key, iv, in_data[0].payload, in_data[0].len,
- &out_msg[pfx_len]);
- #else /*CRYSPR_HAS_AESCTR*/
- /* Create CtrStream. May be longer than in_len (next cryspr block size boundary) */
- int iret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
- if (iret) {
- return(iret);
- }
- /* Reserve output buffer for cryspr */
- out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, cryspr_cb->ctr_stream_len);
- /* Create KeyStream (encrypt CtrStream) */
- iret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
- cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
- &out_msg[pfx_len], &out_len);
- if (iret) {
- HCRYPT_LOG(LOG_ERR, "%s", "hcOpenSSL_AES_ecb_cipher(encrypt, failed\n");
- return(iret);
- }
- #endif/*CRYSPR_HAS_AESCTR*/
- }
- /* Prepend packet prefix (clear text) in output buffer */
- memcpy(out_msg, in_data[0].pfx, pfx_len);
- /* CTR mode output length is same as input, no padding */
- out_len = in_data[0].len;
- if (ctx->mode == HCRYPT_CTX_MODE_AESGCM)
- {
- memcpy(out_msg + pfx_len + out_len, tag, sizeof(tag));
- out_len += sizeof(tag);
- }
- break;
- }
- case HCRYPT_CTX_MODE_CLRTXT: /* Clear text mode (transparent mode for tests) */
- memcpy(&out_msg[pfx_len], in_data[0].payload, in_data[0].len);
- memcpy(out_msg, in_data[0].pfx, pfx_len);
- out_len = in_data[0].len;
- break;
- default:
- /* Unsupported cipher mode */
- return(-1);
- }
- if (out_len <= 0) {
- /*
- * Nothing out
- * This is not an error for implementations using deferred/async processing
- * with co-processor, DSP, crypto hardware, etc.
- * Submitted input data could be returned encrypted in a next call.
- */
- if (nbout_p != NULL) *nbout_p = 0;
- return(-1);
- }
- /* Encrypted messages have been produced */
- if (NULL == out_p) {
- /*
- * Application did not provided output buffer,
- * so copy encrypted message back in input buffer
- */
- memcpy(in_data[0].pfx, out_msg, pfx_len);
- #if !CRYSPR_HAS_AESCTR
- if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
- /* XOR KeyStream with input text directly in input buffer */
- hcrypt_XorStream(in_data[0].payload, &out_msg[pfx_len], out_len);
- }else{
- /* Copy output data back in input buffer */
- memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
- }
- #else /* CRYSPR_HAS_AESCTR */
- /* Copy output data back in input buffer */
- memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
- if (ctx->mode == HCRYPT_CTX_MODE_AESGCM) {
- // Encoding produced more payload (auth tag).
- return (int)out_len;
- }
- #endif /* CRYSPR_HAS_AESCTR */
- } else {
- /* Copy header in output buffer if needed */
- if (pfx_len > 0) memcpy(out_msg, in_data[0].pfx, pfx_len);
- #if !CRYSPR_HAS_AESCTR
- if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
- hcrypt_XorStream(&out_msg[pfx_len], in_data[0].payload, out_len);
- }
- #endif /* CRYSPR_HAS_AESCTR */
- out_p[0] = out_msg;
- out_len_p[0] = pfx_len + out_len;
- *nbout_p = 1;
- }
- return(0);
- }
- static int crysprFallback_MsDecrypt(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx,
- hcrypt_DataDesc *in_data, int nbin ATR_UNUSED, void *out_p[], size_t out_len_p[], int *nbout_p)
- {
- unsigned char *out_txt;
- size_t out_len;
- int iret = 0;
- ASSERT(NULL != cryspr_cb);
- ASSERT(NULL != ctx);
- ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
- /* Reserve output buffer (w/no header) */
- out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, in_data[0].len);
- if (NULL != out_txt) {
- switch(ctx->mode) {
- case HCRYPT_CTX_MODE_AESCTR:
- case HCRYPT_CTX_MODE_AESGCM:
- {
- /* Get current key (odd|even) from context */
- CRYSPR_AESCTX *aes_key = CRYSPR_GETSEK(cryspr_cb, hcryptCtx_GetKeyIndex(ctx));
- unsigned char iv[CRYSPR_AESBLKSZ];
- /* Get input packet index (in network order) */
- hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
- /*
- * Compute the Initial Vector
- * IV (128-bit):
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | 0s | pki | ctr |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * XOR
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | nonce +
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * pki (32-bit): packet index
- * ctr (16-bit): block counter
- * nonce (112-bit): number used once (salt)
- */
- hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
- if (ctx->mode == HCRYPT_CTX_MODE_AESGCM)
- {
- unsigned char* tag = in_data[0].payload + in_data[0].len - HAICRYPT_AUTHTAG_MAX;
- int liret = cryspr_cb->cryspr->aes_gcm_cipher(false, aes_key, iv, in_data[0].pfx, ctx->msg_info->pfx_len, in_data[0].payload, in_data[0].len - HAICRYPT_AUTHTAG_MAX,
- out_txt, tag);
- if (liret) {
- return(liret);
- }
- out_len = in_data[0].len - HAICRYPT_AUTHTAG_MAX;
- }
- else {
- #if CRYSPR_HAS_AESCTR
- cryspr_cb->cryspr->aes_ctr_cipher(false, aes_key, iv, in_data[0].payload, in_data[0].len,
- out_txt);
- out_len = in_data[0].len;
- #else /*CRYSPR_HAS_AESCTR*/
- /* Get input packet index (in network order) */
- hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
- /*
- * Compute the Initial Vector
- * IV (128-bit):
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | 0s | pki | ctr |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * XOR
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | nonce +
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * pki (32-bit): packet index
- * ctr (16-bit): block counter
- * nonce (112-bit): number used once (salt)
- */
- hcrypt_SetCtrIV((unsigned char*)&pki, ctx->salt, iv);
- /* Create CtrStream. May be longer than in_len (next cipher block size boundary) */
- int liret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
- if (liret) {
- return(liret);
- }
- /* Reserve output buffer for cryspr */
- out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, cryspr_cb->ctr_stream_len);
- /* Create KeyStream (encrypt CtrStream) */
- liret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
- cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
- out_txt, &out_len);
- if (liret) {
- HCRYPT_LOG(LOG_ERR, "%s", "crysprNatural_AES_ecb_cipher(encrypt failed\n");
- return(liret);
- }
- #endif /*CRYSPR_HAS_AESCTR*/
- }
- break;
- }
- case HCRYPT_CTX_MODE_CLRTXT:
- memcpy(out_txt, in_data[0].payload, in_data[0].len);
- out_len = in_data[0].len;
- break;
- default:
- return(-1);
- }
- } else {
- return(-1);
- }
- if (out_len > 0) {
- if (NULL == out_p) {
- /*
- * Application did not provided output buffer,
- * so copy encrypted message back in input buffer
- */
- #if !CRYSPR_HAS_AESCTR
- if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
- /* XOR KeyStream with input text directly in input buffer */
- hcrypt_XorStream(in_data[0].payload, out_txt, out_len);
- }else{
- /* Copy output data back in input buffer */
- memcpy(in_data[0].payload, out_txt, out_len);
- }
- #else /* CRYSPR_HAS_AESCTR */
- /* Copy output data back in input buffer */
- memcpy(in_data[0].payload, out_txt, out_len);
- in_data->len = out_len;
- #endif /* CRYSPR_HAS_AESCTR */
- } else {
- /* Copy header in output buffer if needed */
- #if !CRYSPR_HAS_AESCTR
- if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
- hcrypt_XorStream(out_txt, in_data[0].payload, out_len);
- }
- #endif /* CRYSPR_HAS_AESCTR */
- out_p[0] = out_txt;
- out_len_p[0] = out_len;
- *nbout_p = 1;
- }
- iret = 0;
- } else {
- if (NULL != nbout_p) *nbout_p = 0;
- iret = -1;
- }
- #if 0
- { /* Debug decryption errors */
- static int nberr = 0;
- if (out_txt[0] != 0x47){
- if ((++nberr == 1)
- || ((nberr > 500) && (0 == ((((unsigned char *)&MSmsg->pki)[2] & 0x0F)|((unsigned char *)&MSmsg->pki)[3])))) {
- HCRYPT_LOG(LOG_DEBUG, "keyindex=%d\n", hcryptCtx_GetKeyIndex(ctx));
- HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
- HCRYPT_PRINTKEY(ctx->salt, ctx->salt_len, "salt");
- }
- } else {
- nberr = 0;
- }
- }
- #endif
- return(iret);
- }
- CRYSPR_methods *crysprInit(CRYSPR_methods *cryspr)
- {
- /* CryptoLib Primitive API */
- cryspr->prng = crysprStub_Prng;
- cryspr->aes_set_key = crysprStub_AES_SetKey;
- cryspr->aes_ecb_cipher = crysprStub_AES_EcbCipher;
- cryspr->aes_ctr_cipher = crysprStub_AES_CtrCipher;
- cryspr->aes_gcm_cipher = crysprStub_AES_GCMCipher;
- cryspr->sha1_msg_digest = crysprStub_SHA1_MsgDigest;
- /* Crypto Session API */
- cryspr->open = crysprFallback_Open;
- cryspr->close = crysprFallback_Close;
- //Keying material (km) encryption
- cryspr->km_pbkdf2 = crysprStub_KmPbkdf2;
- cryspr->km_setkey = crysprFallback_KmSetKey;
- cryspr->km_wrap = crysprFallback_AES_WrapKey;
- cryspr->km_unwrap = crysprFallback_AES_UnwrapKey;
- //Media stream (ms) encryption
- cryspr->ms_setkey = crysprFallback_MsSetKey;
- cryspr->ms_encrypt = crysprFallback_MsEncrypt;
- cryspr->ms_decrypt = crysprFallback_MsDecrypt;
- return(cryspr);
- }
- HaiCrypt_Cryspr HaiCryptCryspr_Get_Instance(void)
- {
- return((HaiCrypt_Cryspr)cryspr4SRT());
- }
|