cryspr-gnutls.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT)
  17. *****************************************************************************/
  18. #include "hcrypt.h"
  19. #include <string.h>
  20. typedef struct tag_crysprGnuTLS_AES_cb {
  21. CRYSPR_cb ccb; /* CRYSPR control block */
  22. /* Add other 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. } crysprGnuTLS_cb;
  28. int crysprGnuTLS_Prng(unsigned char *rn, int len)
  29. {
  30. return(gnutls_rnd(GNUTLS_RND_KEY,(rn),(len)) < 0 ? -1 : 0);
  31. }
  32. int crysprGnuTLS_AES_SetKey(
  33. int cipher_type, /* One of HCRYPT_CTX_MODE_[CLRTXT|AESECB|AESCTR] */
  34. bool bEncrypt, /* true:encrypt key, false:decrypt key*/
  35. const unsigned char *kstr, /* key string */
  36. size_t kstr_len, /* kstr length 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)cipher_type;
  40. if (bEncrypt) { /* Encrypt key */
  41. if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
  42. HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) bad length\n");
  43. return -1;
  44. }
  45. aes_set_encrypt_key (aes_key, kstr_len, kstr);
  46. } else { /* Decrypt key */
  47. if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
  48. HCRYPT_LOG(LOG_ERR, "%s", "AES_set_decrypt_key(kek) bad length\n");
  49. return -1;
  50. }
  51. aes_set_decrypt_key (aes_key, kstr_len, kstr);
  52. }
  53. return(0);
  54. }
  55. int crysprGnuTLS_AES_EcbCipher( /* AES Electronic Codebook cipher*/
  56. bool bEncrypt, /* true:encrypt, false:decrypt */
  57. CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
  58. const unsigned char *indata,/* src (clear text)*/
  59. size_t inlen, /* length */
  60. unsigned char *out_txt, /* dst (cipher text) */
  61. size_t *outlen) /* dst len */
  62. {
  63. int nblk = inlen/CRYSPR_AESBLKSZ;
  64. int nmore = inlen%CRYSPR_AESBLKSZ;
  65. int i;
  66. if (bEncrypt) {
  67. /* Encrypt packet payload, block by block, in output buffer */
  68. for (i=0; i<nblk; i++){
  69. aes_encrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(i*CRYSPR_AESBLKSZ)], &indata[(i*CRYSPR_AESBLKSZ)]);
  70. }
  71. /* Encrypt last incomplete block */
  72. if (0 < nmore) {
  73. unsigned char intxt[CRYSPR_AESBLKSZ];
  74. memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
  75. memset(intxt+nmore, 0, CRYSPR_AESBLKSZ-nmore);
  76. aes_encrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(nblk*CRYSPR_AESBLKSZ)], intxt);
  77. nblk++;
  78. }
  79. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  80. } else { /* Decrypt */
  81. for (i=0; i<nblk; i++){
  82. aes_decrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(i*CRYSPR_AESBLKSZ)], &indata[(i*CRYSPR_AESBLKSZ)]);
  83. }
  84. /* Encrypt last incomplete block */
  85. if (0 < nmore) {
  86. //shall not happens in decrypt
  87. }
  88. if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
  89. }
  90. return 0;
  91. }
  92. int crysprGnuTLS_AES_CtrCipher( /* AES-CTR128 Encryption */
  93. bool bEncrypt, /* true:encrypt, false:decrypt */
  94. CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
  95. unsigned char *iv, /* iv */
  96. const unsigned char *indata,/* src */
  97. size_t inlen, /* src length */
  98. unsigned char *out_txt) /* dest buffer[inlen] */
  99. {
  100. (void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
  101. ctr_crypt (aes_key, /* ctx */
  102. (nettle_cipher_func*)aes_encrypt, /* nettle_cipher_func */
  103. CRYSPR_AESBLKSZ, /* cipher blocksize */
  104. iv, /* iv */
  105. inlen, /* length */
  106. out_txt, /* dest */
  107. indata); /* src */
  108. return 0;
  109. }
  110. #ifdef CRYSPR2
  111. static CRYSPR_cb *crysprGnuTLS_Open(CRYSPR_methods *cryspr, size_t max_len)
  112. {
  113. crysprGnuTLS_cb *aes_data;
  114. CRYSPR_cb *cryspr_cb;
  115. aes_data = (crysprGnuTLS_cb *)crysprHelper_Open(cryspr, sizeof(crysprGnuTLS_cb), max_len);
  116. if (NULL == aes_data) {
  117. HCRYPT_LOG(LOG_ERR, "crysprHelper_Open(%p, %zd, %zd) failed\n", cryspr, sizeof(crysprGnuTLS_cb), max_len);
  118. return(NULL);
  119. }
  120. aes_data->ccb.aes_kek = &aes_data->aes_kek_buf; //key encrypting key
  121. aes_data->ccb.aes_sek[0] = &aes_data->aes_sek_buf[0]; //stream encrypting key
  122. aes_data->ccb.aes_sek[1] = &aes_data->aes_sek_buf[1]; //stream encrypting key
  123. return(&aes_data->ccb);
  124. }
  125. static int crysprGnuTLS_Close(CRYSPR_cb *cryspr_cb)
  126. {
  127. return(crysprHelper_Close(cryspr_cb));
  128. }
  129. #endif /* CRYSPR2 */
  130. #ifdef CRYSPR_HAS_PBKDF2
  131. /*
  132. * Password-based Key Derivation Function
  133. */
  134. int crysprGnuTLS_KmPbkdf2(
  135. CRYSPR_cb *cryspr_cb,
  136. char *passwd, /* passphrase */
  137. size_t passwd_len, /* passphrase len */
  138. unsigned char *salt, /* salt */
  139. size_t salt_len, /* salt_len */
  140. int itr, /* iterations */
  141. size_t key_len, /* key_len */
  142. unsigned char *out) /* derived key buffer[key_len]*/
  143. {
  144. (void)cryspr_cb;
  145. pbkdf2_hmac_sha1(passwd_len,(const uint8_t *)passwd,itr,salt_len,salt,key_len,out);
  146. return(0);
  147. }
  148. #endif /* CRYSPR_HAS_PBKDF2 */
  149. static CRYSPR_methods crysprGnuTLS_methods;
  150. CRYSPR_methods *crysprGnuTLS(void)
  151. {
  152. if(NULL == crysprGnuTLS_methods.open) {
  153. crysprInit(&crysprGnuTLS_methods); /* Set default methods */
  154. /* CryptoLib Primitive API */
  155. crysprGnuTLS_methods.prng = crysprGnuTLS_Prng;
  156. crysprGnuTLS_methods.aes_set_key = crysprGnuTLS_AES_SetKey;
  157. #if CRYSPR_HAS_AESCTR
  158. crysprGnuTLS_methods.aes_ctr_cipher = crysprGnuTLS_AES_CtrCipher;
  159. #endif
  160. #if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
  161. /* AES-ECB only required if cryspr has no AES-CTR or no AES KeyWrap */
  162. crysprGnuTLS_methods.aes_ecb_cipher = crysprGnuTLS_AES_EcbCipher;
  163. #endif
  164. #if !CRYSPR_HAS_PBKDF2
  165. crysprGnuTLS_methods.sha1_msg_digest= crysprGnuTLS_SHA1_MsgDigest; //Onl required if using generic KmPbkdf2
  166. #endif
  167. //--Crypto Session (Top API)
  168. #ifdef CRYSPR2
  169. crysprGnuTLS_methods.open = crysprGnuTLS_Open;
  170. crysprGnuTLS_methods.close = crysprGnuTLS_Close;
  171. #else /* CRYSPR2 */
  172. // crysprGnuTLS_methods.open =
  173. // crysprGnuTLS_methods.close =
  174. #endif /* CRYSPR2 */
  175. //--Keying material (km) encryption
  176. #if CRYSPR_HAS_PBKDF2
  177. crysprGnuTLS_methods.km_pbkdf2 = crysprGnuTLS_KmPbkdf2;
  178. #endif
  179. // crysprGnuTLS_methods.km_setkey =
  180. // crysprGnuTLS_methods.km_wrap =
  181. // crysprGnuTLS_methods.km_unwrap =
  182. //--Media stream (ms) encryption
  183. // crysprGnuTLS_methods.ms_setkey =
  184. // crysprGnuTLS_methods.ms_encrypt =
  185. // crysprGnuTLS_methods.ms_decrypt =
  186. }
  187. return(&crysprGnuTLS_methods);
  188. }