cryspr-mbedtls.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. 2022-05-19 (jdube)
  14. CRYSPR2 adaptation
  15. 2019-06-27 (jdube)
  16. MBedTLS CRYSPR/4SRT (CRYypto Service PRovider for SRT)
  17. *****************************************************************************/
  18. #include "hcrypt.h"
  19. #include <string.h>
  20. #include <mbedtls/aes.h>
  21. #include <mbedtls/md.h>
  22. #include <mbedtls/pkcs5.h>
  23. #include <mbedtls/entropy.h>
  24. // Static members of cryspr::mbedtls class.
  25. static mbedtls_ctr_drbg_context crysprMbedtls_ctr_drbg;
  26. static mbedtls_entropy_context crysprMbedtls_entropy;
  27. typedef struct tag_crysprMBedTLS_AES_cb {
  28. CRYSPR_cb ccb; /* CRYSPR control block */
  29. /* Add other cryptolib specific data here */
  30. #ifdef CRYSPR2
  31. CRYSPR_AESCTX aes_kek_buf; /* Key Encrypting Key (KEK) */
  32. CRYSPR_AESCTX aes_sek_buf[2]; /* even/odd Stream Encrypting Key (SEK) */
  33. #endif
  34. } crysprMbedtls_cb;
  35. int crysprMbedtls_Prng(unsigned char *rn, int len)
  36. {
  37. int ret = mbedtls_ctr_drbg_random( &crysprMbedtls_ctr_drbg, rn, len );
  38. if (ret != 0)
  39. {
  40. return -1;
  41. }
  42. return 0;
  43. }
  44. int crysprMbedtls_AES_SetKey(
  45. int cipher_type, /* One of HCRYPT_CTX_MODE_[CLRTXT|AESECB|AESCTR] */
  46. bool bEncrypt, /* true:encrypt key, false:decrypt key*/
  47. const unsigned char *kstr, /* key string */
  48. size_t kstr_len, /* kstr length in bytes (16, 24, or 32 bytes, for AES128,AES192, or AES256) */
  49. CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
  50. {
  51. (void)cipher_type;
  52. if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
  53. HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) bad length\n");
  54. return -1;
  55. }
  56. int ret;
  57. #ifdef CRYSPR2
  58. (void)cipher_type;
  59. #endif
  60. // mbedtls uses the "bits" convention (128, 192, 254), just like openssl.
  61. // kstr_len is in "bytes" convention (16, 24, 32).
  62. if (bEncrypt) { /* Encrypt key */
  63. ret = mbedtls_aes_setkey_enc(aes_key, kstr, (unsigned int)kstr_len*8);
  64. } else { /* Decrypt key */
  65. ret = mbedtls_aes_setkey_dec(aes_key, kstr, (unsigned int)kstr_len*8);
  66. }
  67. return ret == 0 ? 0 : -1;
  68. }
  69. int crysprMbedtls_AES_EcbCipher( /* AES Electronic Codebook cipher*/
  70. bool bEncrypt, /* true:encrypt, false:decrypt */
  71. CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
  72. const unsigned char *indata,/* src (clear text)*/
  73. size_t inlen, /* length */
  74. unsigned char *out_txt, /* dst (cipher text) */
  75. size_t *outlen) /* dst len */
  76. {
  77. int nblk = (int)(inlen/CRYSPR_AESBLKSZ);
  78. int nmore = (int)(inlen%CRYSPR_AESBLKSZ);
  79. int i;
  80. if (bEncrypt) {
  81. /* Encrypt packet payload, block by block, in output buffer */
  82. for (i = 0; i < nblk; i++) {
  83. // NOTE: CRYSPR_AESBLKSZ is implicitly the ONLY POSSIBLE
  84. // size of the block.
  85. mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT,
  86. &indata[(i*CRYSPR_AESBLKSZ)],
  87. &out_txt[(i*CRYSPR_AESBLKSZ)]);
  88. }
  89. /* Encrypt last incomplete block */
  90. if (0 < nmore) {
  91. unsigned char intxt[CRYSPR_AESBLKSZ];
  92. memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
  93. memset(intxt+nmore, 0, CRYSPR_AESBLKSZ-nmore);
  94. mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT,
  95. intxt,
  96. &out_txt[(nblk*CRYSPR_AESBLKSZ)]);
  97. nblk++;
  98. }
  99. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  100. } else { /* Decrypt */
  101. for (i=0; i<nblk; i++){
  102. mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_DECRYPT,
  103. &indata[(i*CRYSPR_AESBLKSZ)],
  104. &out_txt[(i*CRYSPR_AESBLKSZ)]);
  105. }
  106. /* Encrypt last incomplete block */
  107. if (0 < nmore) {
  108. //shall not happens in decrypt
  109. }
  110. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  111. }
  112. return 0;
  113. }
  114. int crysprMbedtls_AES_CtrCipher( /* AES-CTR128 Encryption */
  115. bool bEncrypt, /* true:encrypt, false:decrypt */
  116. CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
  117. unsigned char *iv, /* iv */
  118. const unsigned char *indata,/* src */
  119. size_t inlen, /* src length */
  120. unsigned char *out_txt) /* dest buffer[inlen] */
  121. {
  122. unsigned char ctr[CRYSPR_AESBLKSZ];
  123. size_t blk_ofs = 0;
  124. (void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
  125. memset(&ctr[0], 0, sizeof(ctr));
  126. mbedtls_aes_crypt_ctr(aes_key,
  127. inlen,
  128. &blk_ofs,
  129. iv,
  130. ctr,
  131. indata,
  132. out_txt);
  133. return 0;
  134. }
  135. #ifdef CRYSPR2
  136. static CRYSPR_cb *crysprMbedtls_Open(CRYSPR_methods *cryspr, size_t max_len)
  137. {
  138. crysprMbedtls_cb *aes_data;
  139. aes_data = (crysprMbedtls_cb *)crysprHelper_Open(cryspr, sizeof(crysprMbedtls_cb), max_len);
  140. if (NULL == aes_data) {
  141. HCRYPT_LOG(LOG_ERR, "crysprHelper_Open(%p, %zd, %zd) failed\n", cryspr, sizeof(crysprMbedtls_cb), max_len);
  142. return(NULL);
  143. }
  144. aes_data->ccb.aes_kek = &aes_data->aes_kek_buf; //key encrypting key
  145. aes_data->ccb.aes_sek[0] = &aes_data->aes_sek_buf[0]; //stream encrypting key
  146. aes_data->ccb.aes_sek[1] = &aes_data->aes_sek_buf[1]; //stream encrypting key
  147. return(&aes_data->ccb);
  148. }
  149. static int crysprMbedtls_Close(CRYSPR_cb *cryspr_cb)
  150. {
  151. return(crysprHelper_Close(cryspr_cb));
  152. }
  153. #endif /* CRYSPR2 */
  154. /*
  155. * Password-based Key Derivation Function
  156. */
  157. int crysprMbedtls_KmPbkdf2(
  158. CRYSPR_cb *cryspr_cb,
  159. char *passwd, /* passphrase */
  160. size_t passwd_len, /* passphrase len */
  161. unsigned char *salt, /* salt */
  162. size_t salt_len, /* salt_len */
  163. int itr, /* iterations */
  164. size_t key_len, /* key_len */
  165. unsigned char *out) /* derived key buffer[key_len]*/
  166. {
  167. (void)cryspr_cb;
  168. const mbedtls_md_info_t* ifo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
  169. if ( ifo == NULL ) {
  170. // XXX report error, log?
  171. return -1;
  172. }
  173. mbedtls_md_context_t mdctx;
  174. mbedtls_md_init(&mdctx);
  175. const int yes_use_hmac = 1;
  176. int ret;
  177. if ( (ret = mbedtls_md_setup(&mdctx, ifo, yes_use_hmac)) != 0 ) {
  178. mbedtls_md_free(&mdctx);
  179. // XXX report error, log?
  180. return ret;
  181. }
  182. ret = mbedtls_pkcs5_pbkdf2_hmac(&mdctx,
  183. (unsigned char*)passwd, passwd_len, salt, salt_len,
  184. itr, (uint32_t)key_len, out);
  185. mbedtls_md_free(&mdctx);
  186. if (ret == 0)
  187. return 0;
  188. // XXX report error, log?
  189. return -1;
  190. }
  191. static CRYSPR_methods crysprMbedtls_methods;
  192. CRYSPR_methods *crysprMbedtls(void)
  193. {
  194. if (crysprMbedtls_methods.open)
  195. return(&crysprMbedtls_methods);
  196. crysprInit(&crysprMbedtls_methods); /* Set default methods */
  197. /* CryptoLib Primitive API */
  198. crysprMbedtls_methods.prng = crysprMbedtls_Prng;
  199. crysprMbedtls_methods.aes_set_key = crysprMbedtls_AES_SetKey;
  200. #if CRYSPR_HAS_AESCTR
  201. crysprMbedtls_methods.aes_ctr_cipher = crysprMbedtls_AES_CtrCipher;
  202. #endif
  203. #if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
  204. /* AES-ECB only required if cryspr has no AES-CTR or no AES KeyWrap */
  205. crysprMbedtls_methods.aes_ecb_cipher = crysprMbedtls_AES_EcbCipher;
  206. #endif
  207. #if !CRYSPR_HAS_PBKDF2
  208. crysprMbedtls_methods.sha1_msg_digest= crysprMbedtls_SHA1_MsgDigest; //Onl required if using generic KmPbkdf2
  209. #endif
  210. //--Crypto Session (Top API)
  211. #ifdef CRYSPR2
  212. crysprMbedtls_methods.open = crysprMbedtls_Open;
  213. crysprMbedtls_methods.close = crysprMbedtls_Close;
  214. #else
  215. // crysprMbedtls_methods.open =
  216. // crysprMbedtls_methods.close =
  217. #endif
  218. //--Keying material (km) encryption
  219. crysprMbedtls_methods.km_pbkdf2 = crysprMbedtls_KmPbkdf2;
  220. // crysprMbedtls_methods.km_setkey =
  221. // crysprMbedtls_methods.km_wrap =
  222. // crysprMbedtls_methods.km_unwrap =
  223. //--Media stream (ms) encryption
  224. // crysprMbedtls_methods.ms_setkey =
  225. // crysprMbedtls_methods.ms_encrypt =
  226. // crysprMbedtls_methods.ms_decrypt =
  227. // Initialize extra static data
  228. mbedtls_entropy_init( &crysprMbedtls_entropy );
  229. mbedtls_ctr_drbg_init( &crysprMbedtls_ctr_drbg );
  230. int ret;
  231. if ( (ret = mbedtls_ctr_drbg_seed( &crysprMbedtls_ctr_drbg, mbedtls_entropy_func,
  232. &crysprMbedtls_entropy, NULL, 0)) != 0 )
  233. {
  234. HCRYPT_LOG(LOG_CRIT, "crysprMbedtls: STATIC INIT FAILED on mbedtls_ctr_drbg_init: -0x%04x", -ret);
  235. return NULL;
  236. }
  237. return(&crysprMbedtls_methods);
  238. }