cryspr-openssl.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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-26 (jdube)
  16. OpenSSL Direct AES CRYSPR/4SRT (CRYypto Service PRovider for SRT).
  17. *****************************************************************************/
  18. #include "hcrypt.h"
  19. #include <string.h>
  20. typedef struct tag_crysprOpenSSL_AES_cb {
  21. CRYSPR_cb ccb;
  22. /* Add cryptolib specific data here */
  23. #ifdef CRYSPR2
  24. CRYSPR_AESCTX aes_kek_buf; /* Key Encrypting Key (KEK) */
  25. CRYSPR_AESCTX aes_sek_buf[2]; /* even/odd Stream Encrypting Key (SEK) */
  26. #endif
  27. } crysprOpenSSL_cb;
  28. int crysprOpenSSL_Prng(unsigned char *rn, int len)
  29. {
  30. return(RAND_bytes(rn, len) <= 0 ? -1 : 0);
  31. }
  32. int crysprOpenSSL_AES_SetKey(
  33. int cipher_type, /* One of HCRYPT_CTX_MODE_[CLRTXT|AESECB|AESCTR] */
  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) /* CRYpto Service PRovider AES Key context */
  38. {
  39. (void)cipher_type;
  40. if (bEncrypt) { /* Encrypt key */
  41. if (AES_set_encrypt_key(kstr, (int)(kstr_len * 8), aes_key)) {
  42. HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) failed\n");
  43. return(-1);
  44. }
  45. } else { /* Decrypt key */
  46. if (AES_set_decrypt_key(kstr, (int)(kstr_len * 8), aes_key)) {
  47. HCRYPT_LOG(LOG_ERR, "%s", "AES_set_decrypt_key(kek) failed\n");
  48. return(-1);
  49. }
  50. }
  51. return(0);
  52. }
  53. #if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
  54. int crysprOpenSSL_AES_EcbCipher(
  55. bool bEncrypt, /* true:encrypt, false:decrypt */
  56. CRYSPR_AESCTX *aes_key, /* CRYpto Service PRovider AES Key context */
  57. const unsigned char *indata,/* src (clear text if encrypt, cipher text otherwise)*/
  58. size_t inlen, /* indata length */
  59. unsigned char *out_txt, /* dst (cipher text if encrypt, clear text otherwise) */
  60. size_t *outlen) /* in/out dst len */
  61. {
  62. int nblk = inlen/CRYSPR_AESBLKSZ;
  63. int nmore = inlen%CRYSPR_AESBLKSZ;
  64. size_t outsiz = (outlen ? *outlen : 0);
  65. int i;
  66. if (outsiz % CRYSPR_AESBLKSZ) return(-1); /* output buf size must be a multiple of AES block size (16) */
  67. if (bEncrypt) {
  68. if (outsiz > 16 && outsiz < (nblk+nmore)*CRYSPR_AESBLKSZ) return(-1); /* output buf size must have room for PKCS7 padding */
  69. /* Encrypt packet payload, block by block, in output buffer */
  70. for (i=0; i<nblk; i++){
  71. AES_ecb_encrypt(&indata[(i*CRYSPR_AESBLKSZ)],
  72. &out_txt[(i*CRYSPR_AESBLKSZ)], aes_key, AES_ENCRYPT);
  73. }
  74. /* Encrypt last incomplete block */
  75. if (0 < nmore) {
  76. unsigned char intxt[CRYSPR_AESBLKSZ];
  77. /* PKCS7 padding: padding value is number of bytes padded */
  78. memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
  79. memset(intxt+nmore, CRYSPR_AESBLKSZ-nmore, CRYSPR_AESBLKSZ-nmore);
  80. AES_ecb_encrypt(intxt, &out_txt[(nblk*CRYSPR_AESBLKSZ)], aes_key, AES_ENCRYPT);
  81. nblk++;
  82. }
  83. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  84. } else { /* Decrypt */
  85. for (i=0; i<nblk; i++){
  86. AES_ecb_encrypt(&indata[(i*CRYSPR_AESBLKSZ)],
  87. &out_txt[(i*CRYSPR_AESBLKSZ)], aes_key, AES_DECRYPT);
  88. }
  89. /* Encrypt last incomplete block */
  90. if (0 < nmore) {
  91. //shall not happens in decrypt
  92. }
  93. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  94. }
  95. return 0;
  96. }
  97. #endif /* !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP) */
  98. int crysprOpenSSL_AES_CtrCipher(
  99. bool bEncrypt, /* true:encrypt, false:decrypt */
  100. CRYSPR_AESCTX *aes_key, /* CRYpto Service PRovider AES Key context */
  101. unsigned char *iv, /* iv */
  102. const unsigned char *indata,/* src */
  103. size_t inlen, /* length */
  104. unsigned char *out_txt) /* dest */
  105. {
  106. unsigned char ctr[CRYSPR_AESBLKSZ];
  107. unsigned blk_ofs = 0;
  108. (void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
  109. memset(&ctr[0], 0, sizeof(ctr));
  110. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL))
  111. CRYPTO_ctr128_encrypt(indata, out_txt,
  112. inlen, aes_key, iv, ctr, &blk_ofs, (block128_f) AES_encrypt);
  113. #else
  114. AES_ctr128_encrypt(indata, out_txt,
  115. inlen, aes_key, iv, ctr, &blk_ofs);
  116. #endif
  117. return 0;
  118. }
  119. #ifdef CRYSPR2
  120. static CRYSPR_cb *crysprOpenSSL_Open(CRYSPR_methods *cryspr, size_t max_len)
  121. {
  122. crysprOpenSSL_cb *aes_data;
  123. aes_data = (crysprOpenSSL_cb *)crysprHelper_Open(cryspr, sizeof(crysprOpenSSL_cb), max_len);
  124. if (NULL == aes_data) {
  125. HCRYPT_LOG(LOG_ERR, "crysprHelper_Open(%p, %zd, %zd) failed\n", cryspr, sizeof(crysprOpenSSL_cb), max_len);
  126. return(NULL);
  127. }
  128. aes_data->ccb.aes_kek = &aes_data->aes_kek_buf; //key encrypting key
  129. aes_data->ccb.aes_sek[0] = &aes_data->aes_sek_buf[0]; //stream encrypting key
  130. aes_data->ccb.aes_sek[1] = &aes_data->aes_sek_buf[1]; //stream encrypting key
  131. return(&aes_data->ccb);
  132. }
  133. #endif /* CRYSPR2 */
  134. /*
  135. * Password-based Key Derivation Function
  136. */
  137. int crysprOpenSSL_KmPbkdf2(
  138. CRYSPR_cb *cryspr_cb,
  139. char *passwd, /* passphrase */
  140. size_t passwd_len, /* passphrase len */
  141. unsigned char *salt, /* salt */
  142. size_t salt_len, /* salt_len */
  143. int itr, /* iterations */
  144. size_t key_len, /* key_len */
  145. unsigned char *out) /* derived key */
  146. {
  147. (void)cryspr_cb;
  148. int rc = PKCS5_PBKDF2_HMAC_SHA1(passwd,(int)passwd_len,salt,(int)salt_len,itr,(int)key_len,out);
  149. return(rc == 1? 0 : -1);
  150. }
  151. #if CRYSPR_HAS_AESKWRAP
  152. int crysprOpenSSL_KmWrap(CRYSPR_cb *cryspr_cb,
  153. unsigned char *wrap,
  154. const unsigned char *sek,
  155. unsigned int seklen)
  156. {
  157. AES_KEY *kek = CRYSPR_GETKEK(cryspr_cb); //key encrypting key
  158. return(((seklen + HAICRYPT_WRAPKEY_SIGN_SZ) == (unsigned int)AES_wrap_key(kek, NULL, wrap, sek, seklen)) ? 0 : -1);
  159. }
  160. int crysprOpenSSL_KmUnwrap(
  161. CRYSPR_cb *cryspr_cb,
  162. unsigned char *sek, //Stream encrypting key
  163. const unsigned char *wrap,
  164. unsigned int wraplen)
  165. {
  166. AES_KEY *kek = CRYSPR_GETKEK(cryspr_cb); //key encrypting key
  167. return(((wraplen - HAICRYPT_WRAPKEY_SIGN_SZ) == (unsigned int)AES_unwrap_key(kek, NULL, sek, wrap, wraplen)) ? 0 : -1);
  168. }
  169. #endif /*CRYSPR_HAS_AESKWRAP*/
  170. static CRYSPR_methods crysprOpenSSL_methods;
  171. CRYSPR_methods *crysprOpenSSL(void)
  172. {
  173. if(NULL == crysprOpenSSL_methods.open) {
  174. crysprInit(&crysprOpenSSL_methods); //Default/fallback methods
  175. crysprOpenSSL_methods.prng = crysprOpenSSL_Prng;
  176. //--CryptoLib Primitive API-----------------------------------------------
  177. crysprOpenSSL_methods.aes_set_key = crysprOpenSSL_AES_SetKey;
  178. #if CRYSPR_HAS_AESCTR
  179. crysprOpenSSL_methods.aes_ctr_cipher = crysprOpenSSL_AES_CtrCipher;
  180. #endif
  181. #if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
  182. /* AES-ECB only required if cryspr has no AES-CTR and no AES KeyWrap */
  183. /* OpenSSL has both AESCTR and AESKWRP and the AESECB wrapper is only used
  184. to test the falback methods */
  185. crysprOpenSSL_methods.aes_ecb_cipher = crysprOpenSSL_AES_EcbCipher;
  186. #endif
  187. #if !CRYSPR_HAS_PBKDF2
  188. crysprOpenSSL_methods.sha1_msg_digest= NULL; //Required to use eventual default/fallback KmPbkdf2
  189. #endif
  190. //--Crypto Session API-----------------------------------------
  191. #ifdef CRYSPR2
  192. crysprOpenSSL_methods.open = crysprOpenSSL_Open;
  193. #else
  194. // crysprOpenSSL_methods.open =
  195. #endif
  196. // crysprOpenSSL_methods.close =
  197. //--Keying material (km) encryption
  198. #if CRYSPR_HAS_PBKDF2
  199. crysprOpenSSL_methods.km_pbkdf2 = crysprOpenSSL_KmPbkdf2;
  200. #else
  201. #error There is no default/fallback method for PBKDF2
  202. #endif
  203. // crysprOpenSSL_methods.km_setkey =
  204. #if CRYSPR_HAS_AESKWRAP
  205. crysprOpenSSL_methods.km_wrap = crysprOpenSSL_KmWrap;
  206. crysprOpenSSL_methods.km_unwrap = crysprOpenSSL_KmUnwrap;
  207. #endif
  208. //--Media stream (ms) encryption
  209. // crysprOpenSSL_methods.ms_setkey =
  210. // crysprOpenSSL_methods.ms_encrypt =
  211. // crysprOpenSSL_methods.ms_decrypt =
  212. }
  213. return(&crysprOpenSSL_methods);
  214. }