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