cryspr.c 22 KB

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