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