1 /*
2 * SRT - Secure, Reliable, Transport
3 * Copyright (c) 2019 Haivision Systems Inc.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 */
10
11
12 /*****************************************************************************
13 written by
14 Haivision Systems Inc.
15
16 2019-06-28 (jdube)
17 CRYSPR/4SRT Initial implementation.
18 *****************************************************************************/
19
20 #include "hcrypt.h"
21 #include "cryspr.h"
22
23 #include <stdlib.h>
24 #include <string.h>
25
crysprStub_Prng(unsigned char * rn,int len)26 int crysprStub_Prng(unsigned char *rn, int len)
27 {
28 (void)rn;
29 (void)len;
30 return(0);
31 }
32
crysprStub_AES_SetKey(bool bEncrypt,const unsigned char * kstr,size_t kstr_len,CRYSPR_AESCTX * aes_key)33 int crysprStub_AES_SetKey(
34 bool bEncrypt, /* true Enxcrypt key, false: decrypt */
35 const unsigned char *kstr, /* key sttring*/
36 size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
37 CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
38 {
39 (void)bEncrypt;
40 (void)kstr;
41 (void)kstr_len;
42 (void)aes_key;
43
44 return(0);
45 }
46
crysprStub_AES_EcbCipher(bool bEncrypt,CRYSPR_AESCTX * aes_key,const unsigned char * indata,size_t inlen,unsigned char * out_txt,size_t * outlen)47 int crysprStub_AES_EcbCipher(
48 bool bEncrypt, /* true:encrypt, false:decrypt */
49 CRYSPR_AESCTX *aes_key, /* AES context */
50 const unsigned char *indata,/* src (clear text)*/
51 size_t inlen, /* length */
52 unsigned char *out_txt, /* dst (cipher text) */
53 size_t *outlen) /* dst len */
54 {
55 (void)bEncrypt;
56 (void)aes_key;
57 (void)indata;
58 (void)inlen;
59 (void)out_txt;
60 (void)outlen;
61
62 return -1;
63 }
64
crysprStub_AES_CtrCipher(bool bEncrypt,CRYSPR_AESCTX * aes_key,unsigned char * iv,const unsigned char * indata,size_t inlen,unsigned char * out_txt)65 int crysprStub_AES_CtrCipher(
66 bool bEncrypt, /* true:encrypt, false:decrypt */
67 CRYSPR_AESCTX *aes_key, /* AES context */
68 unsigned char *iv, /* iv */
69 const unsigned char *indata,/* src */
70 size_t inlen, /* length */
71 unsigned char *out_txt) /* dest */
72 {
73 (void)bEncrypt;
74 (void)aes_key;
75 (void)iv;
76 (void)indata;
77 (void)inlen;
78 (void)out_txt;
79
80 return(-1);
81 }
82
crysprStub_SHA1_MsgDigest(const unsigned char * m,size_t m_len,unsigned char * md)83 unsigned char *crysprStub_SHA1_MsgDigest(
84 const unsigned char *m, /* in: message */
85 size_t m_len, /* message length */
86 unsigned char *md) /* out: message digest buffer *160 bytes */
87 {
88 (void)m;
89 (void)m_len;
90 (void)md;
91
92 return(NULL);//return md;
93 }
94
95 /*
96 * Password-based Key Derivation Function
97 */
crysprStub_KmPbkdf2(CRYSPR_cb * cryspr_cb,char * passwd,size_t passwd_len,unsigned char * salt,size_t salt_len,int itr,size_t key_len,unsigned char * out)98 int crysprStub_KmPbkdf2(
99 CRYSPR_cb *cryspr_cb,
100 char *passwd, /* passphrase */
101 size_t passwd_len, /* passphrase len */
102 unsigned char *salt, /* salt */
103 size_t salt_len, /* salt_len */
104 int itr, /* iterations */
105 size_t key_len, /* key_len */
106 unsigned char *out) /* derived key */
107 {
108 (void)cryspr_cb;
109 (void)passwd;
110 (void)passwd_len;
111 (void)salt;
112 (void)salt_len;
113 (void)itr;
114 (void)key_len;
115 (void)out;
116
117 /* >>Todo:
118 * develop PBKDF2 using SHA1 primitive cryspr_cb->cryspr->sha1_msg_digest() for cryptolibs not providing it
119 */
120 return(-1);
121 }
122
crysprFallback_KmSetKey(CRYSPR_cb * cryspr_cb,bool bWrap,const unsigned char * kek,size_t kek_len)123 static int crysprFallback_KmSetKey(CRYSPR_cb *cryspr_cb, bool bWrap, const unsigned char *kek, size_t kek_len)
124 {
125 CRYSPR_AESCTX *aes_kek = &cryspr_cb->aes_kek;
126
127 if (cryspr_cb->cryspr->aes_set_key(bWrap, kek, kek_len, aes_kek)) {
128 HCRYPT_LOG(LOG_ERR, "AES_set_%s_key(kek) failed\n", bWrap? "encrypt": "decrypt");
129 return(-1);
130 }
131 return(0);
132 }
133
134 /*
135 * AES_wrap_key()/AES_unwrap_key() introduced in openssl 0.9.8h
136 * Here is an implementation using AES native API for cryspr not providing it.
137 */
138
139 static const unsigned char default_iv[] = {
140 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
141 };
crysprFallback_AES_WrapKey(CRYSPR_cb * cryspr_cb,unsigned char * out,const unsigned char * in,unsigned int inlen)142 int crysprFallback_AES_WrapKey(CRYSPR_cb *cryspr_cb,
143 unsigned char *out,
144 const unsigned char *in,
145 unsigned int inlen)
146 {
147 unsigned char *A, B[16], *R;
148 const unsigned char *iv = default_iv;
149 unsigned int i, j, t;
150 if ((inlen & 0x7) || (inlen < 8))
151 return -1;
152 A = B;
153 t = 1;
154 memcpy(out + 8, in, inlen);
155
156 memcpy(A, iv, 8);
157
158 for (j = 0; j < 6; j++)
159 {
160 R = out + 8;
161 for (i = 0; i < inlen; i += 8, t++, R += 8)
162 {
163 memcpy(B + 8, R, 8);
164 {
165 size_t outlen = 16;
166 cryspr_cb->cryspr->aes_ecb_cipher(true, &cryspr_cb->aes_kek, B, 16, B, &outlen);
167 }
168 A[7] ^= (unsigned char)(t & 0xff);
169 if (t > 0xff)
170 {
171 A[6] ^= (unsigned char)((t >> 8) & 0xff);
172 A[5] ^= (unsigned char)((t >> 16) & 0xff);
173 A[4] ^= (unsigned char)((t >> 24) & 0xff);
174 }
175 memcpy(R, B + 8, 8);
176 }
177 }
178 memcpy(out, A, 8);
179 return 0;
180 }
181
crysprFallback_AES_UnwrapKey(CRYSPR_cb * cryspr_cb,unsigned char * out,const unsigned char * in,unsigned int inlen)182 int crysprFallback_AES_UnwrapKey(CRYSPR_cb *cryspr_cb,
183 unsigned char *out,
184 const unsigned char *in,
185 unsigned int inlen)
186 {
187 unsigned char *A, B[16], *R;
188 const unsigned char *iv = default_iv;
189 unsigned int i, j, t;
190 inlen -= 8;
191 if (inlen & 0x7)
192 return -1;
193 if (inlen < 8)
194 return -1;
195 A = B;
196 t = 6 * (inlen >> 3);
197 memcpy(A, in, 8);
198 memcpy(out, in + 8, inlen);
199 for (j = 0; j < 6; j++)
200 {
201 R = out + inlen - 8;
202 for (i = 0; i < inlen; i += 8, t--, R -= 8)
203 {
204 A[7] ^= (unsigned char)(t & 0xff);
205 if (t > 0xff)
206 {
207 A[6] ^= (unsigned char)((t >> 8) & 0xff);
208 A[5] ^= (unsigned char)((t >> 16) & 0xff);
209 A[4] ^= (unsigned char)((t >> 24) & 0xff);
210 }
211 memcpy(B + 8, R, 8);
212 {
213 size_t outlen = 16;
214 cryspr_cb->cryspr->aes_ecb_cipher(false, &cryspr_cb->aes_kek, B, 16, B, &outlen);
215 }
216 memcpy(R, B + 8, 8);
217 }
218 }
219 if (memcmp(A, iv, 8))
220 {
221 memset(out, 0, inlen);
222 return -1;
223 }
224 return 0;
225 }
226
_crysprFallback_GetOutbuf(CRYSPR_cb * cryspr_cb,size_t pfx_len,size_t out_len)227 static unsigned char *_crysprFallback_GetOutbuf(CRYSPR_cb *cryspr_cb, size_t pfx_len, size_t out_len)
228 {
229 unsigned char *out_buf;
230
231 if ((pfx_len + out_len) > (cryspr_cb->outbuf_siz - cryspr_cb->outbuf_ofs)) {
232 /* Not enough room left, circle buffers */
233 cryspr_cb->outbuf_ofs = 0;
234 }
235 out_buf = &cryspr_cb->outbuf[cryspr_cb->outbuf_ofs];
236 cryspr_cb->outbuf_ofs += (pfx_len + out_len);
237 return(out_buf);
238 }
239
crysprFallback_Open(CRYSPR_methods * cryspr,size_t max_len)240 static CRYSPR_cb *crysprFallback_Open(CRYSPR_methods *cryspr, size_t max_len)
241 {
242 CRYSPR_cb *cryspr_cb;
243 unsigned char *membuf;
244 size_t memsiz, padded_len = hcryptMsg_PaddedLen(max_len, 128/8);
245
246 HCRYPT_LOG(LOG_DEBUG, "%s", "Using OpenSSL AES\n");
247
248 memsiz = sizeof(*cryspr_cb) + (CRYSPR_OUTMSGMAX * padded_len);
249 #if !CRYSPR_HAS_AESCTR
250 memsiz += HCRYPT_CTR_STREAM_SZ;
251 #endif /* !CRYSPR_HAS_AESCTR */
252
253 cryspr_cb = malloc(memsiz);
254 if (NULL == cryspr_cb) {
255 HCRYPT_LOG(LOG_ERR, "malloc(%zd) failed\n", memsiz);
256 return(NULL);
257 }
258 membuf = (unsigned char *)cryspr_cb;
259 membuf += sizeof(*cryspr_cb);
260
261 #if !CRYSPR_HAS_AESCTR
262 cryspr_cb->ctr_stream = membuf;
263 membuf += HCRYPT_CTR_STREAM_SZ;
264 cryspr_cb->ctr_stream_siz = HCRYPT_CTR_STREAM_SZ;
265 cryspr_cb->ctr_stream_len = 0;
266 #endif /* !CRYSPR_HAS_AESCTR */
267
268 cryspr_cb->outbuf = membuf;
269 cryspr_cb->outbuf_siz = CRYSPR_OUTMSGMAX * padded_len;
270 cryspr_cb->outbuf_ofs = 0;
271 // membuf += cryspr_cb->outbuf_siz;
272
273 cryspr_cb->cryspr=(CRYSPR_methods *)cryspr;
274
275 return(cryspr_cb);
276 }
277
crysprFallback_Close(CRYSPR_cb * cryspr_cb)278 static int crysprFallback_Close(CRYSPR_cb *cryspr_cb)
279 {
280 free(cryspr_cb);
281 return(0);
282 }
283
crysprFallback_MsSetKey(CRYSPR_cb * cryspr_cb,hcrypt_Ctx * ctx,const unsigned char * key,size_t key_len)284 static int crysprFallback_MsSetKey(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, const unsigned char *key, size_t key_len)
285 {
286 CRYSPR_AESCTX *aes_sek = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)]; /* Ctx tells if it's for odd or even key */
287
288 if ((ctx->flags & HCRYPT_CTX_F_ENCRYPT) /* Encrypt key */
289 || (ctx->mode == HCRYPT_CTX_MODE_AESCTR)) { /* CTR mode decrypts using encryption methods */
290 if (cryspr_cb->cryspr->aes_set_key(true, key, key_len, aes_sek)) {
291 HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_encrypt_key(sek) failed\n");
292 return(-1);
293 }
294 } else { /* Decrypt key */
295 if (cryspr_cb->cryspr->aes_set_key(false, key, key_len, aes_sek)) {
296 HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_decrypt_key(sek) failed\n");
297 return(-1);
298 }
299 }
300 return(0);
301 }
302
303 #if !CRYSPR_HAS_AESCTR
_crysprFallback_AES_SetCtrStream(CRYSPR_cb * cryspr_cb,hcrypt_Ctx * ctx,size_t len,unsigned char * iv)304 static int _crysprFallback_AES_SetCtrStream(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, size_t len, unsigned char *iv)
305 {
306 /* Counter stream:
307 * 0 1 2 3 4 5 nblk
308 * +---+---+---+---+---+---+---+---+
309 * |blk|blk|blk|blk|blk|blk|...|blk|
310 * +---+---+---+---+---+---+---+---+
311 */
312
313 /* IV (128-bit):
314 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
315 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
316 * | 0s | pki | ctr |
317 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
318 * XOR
319 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
320 * | nonce +
321 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
322 *
323 * pki (32-bit): packet index
324 * ctr (16-bit): block counter
325 * nonce (112-bit): number used once (salt)
326 */
327 unsigned char ctr[HCRYPT_CTR_BLK_SZ];
328 unsigned nblk;
329
330 ASSERT(NULL != cryspr_cb);
331 ASSERT(NULL != ctx);
332
333 memcpy(ctr, iv, HCRYPT_CTR_BLK_SZ);
334
335 nblk = (len + (HCRYPT_CTR_BLK_SZ-1))/HCRYPT_CTR_BLK_SZ;
336 if ((nblk * HCRYPT_CTR_BLK_SZ) <= cryspr_cb->ctr_stream_siz) {
337 unsigned blk;
338 unsigned char *csp = &cryspr_cb->ctr_stream[0];
339
340 for(blk = 0; blk < nblk; blk++) {
341 memcpy(csp, ctr, HCRYPT_CTR_BLK_SZ);
342 csp += HCRYPT_CTR_BLK_SZ;
343 if (0 == ++(ctr[HCRYPT_CTR_BLK_SZ-1])) ++(ctr[HCRYPT_CTR_BLK_SZ-2]);
344 }
345 cryspr_cb->ctr_stream_len = nblk * HCRYPT_CTR_BLK_SZ;
346 } else {
347 HCRYPT_LOG(LOG_ERR, "packet too long(%zd)\n", len);
348 return(-1);
349 }
350 return(0);
351 }
352 #endif
353
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)354 static int crysprFallback_MsEncrypt(
355 CRYSPR_cb *cryspr_cb,
356 hcrypt_Ctx *ctx,
357 hcrypt_DataDesc *in_data, int nbin ATR_UNUSED,
358 void *out_p[], size_t out_len_p[], int *nbout_p)
359 {
360 unsigned char *out_msg;
361 size_t out_len = 0; //payload size
362 int pfx_len;
363
364 ASSERT(NULL != ctx);
365 ASSERT(NULL != cryspr_cb);
366 ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
367
368 /*
369 * Get message prefix length
370 * to reserve room for unencrypted message header in output buffer
371 */
372 pfx_len = ctx->msg_info->pfx_len;
373
374 /* Get buffer room from the internal circular output buffer */
375 out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, in_data[0].len);
376
377 if (NULL != out_msg) {
378 switch(ctx->mode) {
379 case HCRYPT_CTX_MODE_AESCTR: /* Counter mode */
380 {
381 #if CRYSPR_HAS_AESCTR
382 /* Get current key (odd|even) from context */
383 CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
384 unsigned char iv[CRYSPR_AESBLKSZ];
385
386 /* Get input packet index (in network order) */
387 hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
388
389 /*
390 * Compute the Initial Vector
391 * IV (128-bit):
392 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
393 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
394 * | 0s | pki | ctr |
395 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
396 * XOR
397 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
398 * | nonce +
399 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
400 *
401 * pki (32-bit): packet index
402 * ctr (16-bit): block counter
403 * nonce (112-bit): number used once (salt)
404 */
405 hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
406
407 cryspr_cb->cryspr->aes_ctr_cipher(true, aes_key, iv, in_data[0].payload, in_data[0].len,
408 &out_msg[pfx_len]);
409 #else /*CRYSPR_HAS_AESCTR*/
410 /* Get current key (odd|even) from context */
411 CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
412 unsigned char iv[CRYSPR_AESBLKSZ];
413 int iret = 0;
414
415 /* Get input packet index (in network order) */
416 hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
417
418 /*
419 * Compute the Initial Vector
420 * IV (128-bit):
421 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
422 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
423 * | 0s | pki | ctr |
424 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
425 * XOR
426 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
427 * | nonce +
428 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
429 *
430 * pki (32-bit): packet index
431 * ctr (16-bit): block counter
432 * nonce (112-bit): number used once (salt)
433 */
434 hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
435
436 /* Create CtrStream. May be longer than in_len (next cryspr block size boundary) */
437 iret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
438 if (iret) {
439 return(iret);
440 }
441 /* Reserve output buffer for cryspr */
442 out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, cryspr_cb->ctr_stream_len);
443
444 /* Create KeyStream (encrypt CtrStream) */
445 iret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
446 cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
447 &out_msg[pfx_len], &out_len);
448 if (iret) {
449 HCRYPT_LOG(LOG_ERR, "%s", "hcOpenSSL_AES_ecb_cipher(encrypt, failed\n");
450 return(iret);
451 }
452 #endif/*CRYSPR_HAS_AESCTR*/
453 /* Prepend packet prefix (clear text) in output buffer */
454 memcpy(out_msg, in_data[0].pfx, pfx_len);
455 /* CTR mode output length is same as input, no padding */
456 out_len = in_data[0].len;
457 break;
458 }
459 case HCRYPT_CTX_MODE_CLRTXT: /* Clear text mode (transparent mode for tests) */
460 memcpy(&out_msg[pfx_len], in_data[0].payload, in_data[0].len);
461 memcpy(out_msg, in_data[0].pfx, pfx_len);
462 out_len = in_data[0].len;
463 break;
464 default:
465 /* Unsupported cipher mode */
466 return(-1);
467 }
468 } else {
469 /* input data too big */
470 return(-1);
471 }
472
473 if (out_len > 0) {
474 /* Encrypted messages have been produced */
475 if (NULL == out_p) {
476 /*
477 * Application did not provided output buffer,
478 * so copy encrypted message back in input buffer
479 */
480 memcpy(in_data[0].pfx, out_msg, pfx_len);
481 #if !CRYSPR_HAS_AESCTR
482 if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
483 /* XOR KeyStream with input text directly in input buffer */
484 hcrypt_XorStream(in_data[0].payload, &out_msg[pfx_len], out_len);
485 }else{
486 /* Copy output data back in input buffer */
487 memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
488 }
489 #else /* CRYSPR_HAS_AESCTR */
490 /* Copy output data back in input buffer */
491 memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
492 #endif /* CRYSPR_HAS_AESCTR */
493 } else {
494 /* Copy header in output buffer if needed */
495 if (pfx_len > 0) memcpy(out_msg, in_data[0].pfx, pfx_len);
496 #if !CRYSPR_HAS_AESCTR
497 if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
498 hcrypt_XorStream(&out_msg[pfx_len], in_data[0].payload, out_len);
499 }
500 #endif /* CRYSPR_HAS_AESCTR */
501 out_p[0] = out_msg;
502 out_len_p[0] = pfx_len + out_len;
503 *nbout_p = 1;
504 }
505 } else {
506 /*
507 * Nothing out
508 * This is not an error for implementations using deferred/async processing
509 * with co-processor, DSP, crypto hardware, etc.
510 * Submitted input data could be returned encrypted in a next call.
511 */
512 if (nbout_p != NULL) *nbout_p = 0;
513 return(-1);
514 }
515 return(0);
516 }
517
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)518 static int crysprFallback_MsDecrypt(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx,
519 hcrypt_DataDesc *in_data, int nbin ATR_UNUSED, void *out_p[], size_t out_len_p[], int *nbout_p)
520 {
521 unsigned char *out_txt;
522 size_t out_len;
523 int iret = 0;
524
525 ASSERT(NULL != cryspr_cb);
526 ASSERT(NULL != ctx);
527 ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
528
529 /* Reserve output buffer (w/no header) */
530 out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, in_data[0].len);
531
532 if (NULL != out_txt) {
533 switch(ctx->mode) {
534 case HCRYPT_CTX_MODE_AESCTR:
535 {
536 #if CRYSPR_HAS_AESCTR
537 /* Get current key (odd|even) from context */
538 CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
539 unsigned char iv[CRYSPR_AESBLKSZ];
540
541 /* Get input packet index (in network order) */
542 hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
543
544 /*
545 * Compute the Initial Vector
546 * IV (128-bit):
547 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
548 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
549 * | 0s | pki | ctr |
550 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
551 * XOR
552 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
553 * | nonce +
554 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
555 *
556 * pki (32-bit): packet index
557 * ctr (16-bit): block counter
558 * nonce (112-bit): number used once (salt)
559 */
560 hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
561
562 cryspr_cb->cryspr->aes_ctr_cipher(false, aes_key, iv, in_data[0].payload, in_data[0].len,
563 out_txt);
564 out_len = in_data[0].len;
565 #else /*CRYSPR_HAS_AESCTR*/
566 /* Get current key (odd|even) from context */
567 CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
568 unsigned char iv[CRYSPR_AESBLKSZ];
569 int iret = 0;
570
571 /* Get input packet index (in network order) */
572 hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
573
574 /*
575 * Compute the Initial Vector
576 * IV (128-bit):
577 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
578 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
579 * | 0s | pki | ctr |
580 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
581 * XOR
582 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
583 * | nonce +
584 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
585 *
586 * pki (32-bit): packet index
587 * ctr (16-bit): block counter
588 * nonce (112-bit): number used once (salt)
589 */
590 hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
591
592 /* Create CtrStream. May be longer than in_len (next cipher block size boundary) */
593 iret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
594 if (iret) {
595 return(iret);
596 }
597 /* Reserve output buffer for cryspr */
598 out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, cryspr_cb->ctr_stream_len);
599
600 /* Create KeyStream (encrypt CtrStream) */
601 iret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
602 cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
603 out_txt, &out_len);
604 if (iret) {
605 HCRYPT_LOG(LOG_ERR, "%s", "crysprNatural_AES_ecb_cipher(encrypt failed\n");
606 return(iret);
607 }
608
609 #endif /*CRYSPR_HAS_AESCTR*/
610 break;
611 }
612 case HCRYPT_CTX_MODE_CLRTXT:
613 memcpy(out_txt, in_data[0].payload, in_data[0].len);
614 out_len = in_data[0].len;
615 break;
616 default:
617 return(-1);
618 }
619 } else {
620 return(-1);
621 }
622
623 if (out_len > 0) {
624 if (NULL == out_p) {
625 /*
626 * Application did not provided output buffer,
627 * so copy encrypted message back in input buffer
628 */
629 #if !CRYSPR_HAS_AESCTR
630 if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
631 /* XOR KeyStream with input text directly in input buffer */
632 hcrypt_XorStream(in_data[0].payload, out_txt, out_len);
633 }else{
634 /* Copy output data back in input buffer */
635 memcpy(in_data[0].payload, out_txt, out_len);
636 }
637 #else /* CRYSPR_HAS_AESCTR */
638 /* Copy output data back in input buffer */
639 memcpy(in_data[0].payload, out_txt, out_len);
640 #endif /* CRYSPR_HAS_AESCTR */
641 } else {
642 /* Copy header in output buffer if needed */
643 #if !CRYSPR_HAS_AESCTR
644 if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
645 hcrypt_XorStream(out_txt, in_data[0].payload, out_len);
646 }
647 #endif /* CRYSPR_HAS_AESCTR */
648 out_p[0] = out_txt;
649 out_len_p[0] = out_len;
650 *nbout_p = 1;
651 }
652 iret = 0;
653 } else {
654 if (NULL != nbout_p) *nbout_p = 0;
655 iret = -1;
656 }
657
658 #if 0
659 { /* Debug decryption errors */
660 static int nberr = 0;
661
662 if (out_txt[0] != 0x47){
663 if ((++nberr == 1)
664 || ((nberr > 500) && (0 == ((((unsigned char *)&MSmsg->pki)[2] & 0x0F)|((unsigned char *)&MSmsg->pki)[3])))) {
665 HCRYPT_LOG(LOG_DEBUG, "keyindex=%d\n", hcryptCtx_GetKeyIndex(ctx));
666 HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
667 HCRYPT_PRINTKEY(ctx->salt, ctx->salt_len, "salt");
668 }
669 } else {
670 nberr = 0;
671 }
672 }
673 #endif
674 return(iret);
675 }
676
677
crysprInit(CRYSPR_methods * cryspr)678 CRYSPR_methods *crysprInit(CRYSPR_methods *cryspr)
679 {
680 /* CryptoLib Primitive API */
681 cryspr->prng = crysprStub_Prng;
682 cryspr->aes_set_key = crysprStub_AES_SetKey;
683 cryspr->aes_ecb_cipher = crysprStub_AES_EcbCipher;
684 cryspr->aes_ctr_cipher = crysprStub_AES_CtrCipher;
685 cryspr->sha1_msg_digest = crysprStub_SHA1_MsgDigest;
686
687
688 /* Crypto Session API */
689 cryspr->open = crysprFallback_Open;
690 cryspr->close = crysprFallback_Close;
691 //Keying material (km) encryption
692 cryspr->km_pbkdf2 = crysprStub_KmPbkdf2;
693 cryspr->km_setkey = crysprFallback_KmSetKey;
694 cryspr->km_wrap = crysprFallback_AES_WrapKey;
695 cryspr->km_unwrap = crysprFallback_AES_UnwrapKey;
696 //Media stream (ms) encryption
697 cryspr->ms_setkey = crysprFallback_MsSetKey;
698 cryspr->ms_encrypt = crysprFallback_MsEncrypt;
699 cryspr->ms_decrypt = crysprFallback_MsDecrypt;
700
701 return(cryspr);
702 }
703
HaiCryptCryspr_Get_Instance(void)704 HaiCrypt_Cryspr HaiCryptCryspr_Get_Instance(void)
705 {
706 return((HaiCrypt_Cryspr)cryspr4SRT());
707 }
708