lsquic_crypto.c revision 5392f7a3
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <string.h>
4
5#include <openssl/ssl.h>
6#include <openssl/crypto.h>
7#include <openssl/stack.h>
8#include <openssl/x509.h>
9#include <openssl/rand.h>
10#include <openssl/curve25519.h>
11#include <openssl/hmac.h>
12
13#include <zlib.h>
14#ifdef WIN32
15#include <vc_compat.h>
16#endif
17
18#include "lsquic_types.h"
19#include "lsquic_crypto.h"
20#include "lsquic_parse.h"
21#include "lsquic_util.h"
22#include "lsquic_str.h"
23
24#define LSQUIC_LOGGER_MODULE LSQLM_CRYPTO
25#include "lsquic_logger.h"
26
27
28static const char s_hs_signature[] = "QUIC CHLO and server config signature";
29static int crypto_inited = 0;
30
31
32void rand_bytes(void *data, int len)
33{
34    RAND_bytes(data, len);
35}
36
37
38uint64_t fnv1a_64(const uint8_t * data, int len)
39{
40    uint64_t hash = UINT64_C(14695981039346656037);
41    const uint8_t *end = data + len;
42    while(data < end)
43    {
44        hash ^= *data;
45        hash *= UINT64_C(1099511628211);
46        ++data;
47    }
48    return hash;
49}
50
51
52void fnv1a_64_s(const uint8_t * data, int len, char *md)
53{
54    uint64_t hash = fnv1a_64(data, len);
55    memcpy(md, (void *)&hash, 8);
56}
57
58
59#if defined( __x86_64 )||defined( __x86_64__ )
60
61static uint128 s_prime;
62static uint128 s_init_hash;
63
64
65static inline void make_uint128(uint128 *v, uint64_t hi, uint64_t lo)
66{
67    *v = hi;
68    *v <<= 64;
69    *v += lo;
70}
71
72
73void fnv1a_inc(uint128 *hash, const uint8_t *data, int len)
74{
75    const uint8_t* end = data + len;
76    while(data < end)
77    {
78        *hash = (*hash ^ (*data)) * s_prime;
79        ++data;
80    }
81}
82
83uint128 fnv1a_128_3(const uint8_t *data1, int len1,
84                      const uint8_t *data2, int len2,
85                      const uint8_t *data3, int len3)
86{
87    uint128 hash;
88    memcpy(&hash, &s_init_hash, 16);
89
90    fnv1a_inc(&hash, data1, len1);
91    fnv1a_inc(&hash, data2, len2);
92    fnv1a_inc(&hash, data3, len3);
93    return hash;
94}
95
96/* HS_PKT_HASH_LENGTH bytes of md */
97void serialize_fnv128_short(uint128 v, uint8_t *md)
98{
99    memcpy(md, (void *)&v, 12);
100}
101
102#else
103uint128  *uint128_times(uint128 *v, const uint128 *factor)
104{
105    uint64_t a96 = v->hi_ >> 32;
106    uint64_t a64 = v->hi_ & 0xffffffffu;
107    uint64_t a32 = v->lo_ >> 32;
108    uint64_t a00 = v->lo_ & 0xffffffffu;
109    uint64_t b96 = factor->hi_ >> 32;
110    uint64_t b64 = factor->hi_ & 0xffffffffu;
111    uint64_t b32 = factor->lo_ >> 32;
112    uint64_t b00 = factor->lo_ & 0xffffffffu;
113    uint64_t tmp, lolo;
114    // multiply [a96 .. a00] x [b96 .. b00]
115    // terms higher than c96 disappear off the high side
116    // terms c96 and c64 are safe to ignore carry bit
117    uint64_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
118    uint64_t c64 = a64 * b00 + a32 * b32 + a00 * b64;
119    v->hi_ = (c96 << 32) + c64;
120    v->lo_ = 0;
121
122    tmp = a32 * b00;
123    v->hi_ += tmp >> 32;
124    v->lo_ += tmp << 32;
125
126    tmp = a00 * b32;
127    v->hi_ += tmp >> 32;
128    v->lo_ += tmp << 32;
129
130    tmp = a00 * b00;
131    lolo = v->lo_ + tmp;
132    if (lolo < v->lo_)
133        ++v->hi_;
134    v->lo_ = lolo;
135
136    return v;
137}
138
139void fnv1a_inc(uint128 *hash, const uint8_t * data, int len)
140{
141    static const uint128 kPrime = {16777216, 315};
142    const uint8_t* end = data + len;
143    while(data < end)
144    {
145        hash->lo_ = (hash->lo_ ^ (uint64_t)*data);
146        uint128_times(hash, &kPrime);
147        ++data;
148    }
149}
150
151
152uint128 fnv1a_128_3(const uint8_t * data1, int len1,
153                      const uint8_t * data2, int len2,
154                      const uint8_t * data3, int len3)
155{
156    uint128 hash = {UINT64_C(7809847782465536322), UINT64_C(7113472399480571277)};
157    fnv1a_inc(&hash, data1, len1);
158    fnv1a_inc(&hash, data2, len2);
159    fnv1a_inc(&hash, data3, len3);
160    return hash;
161}
162
163
164/* HS_PKT_HASH_LENGTH bytes of md */
165void serialize_fnv128_short(uint128 v, uint8_t *md)
166{
167    assert(HS_PKT_HASH_LENGTH == 8 + 4);
168    memcpy(md, (void *)&v.lo_, 8);
169    memcpy(md + 8, (void *)&v.hi_, 4);
170}
171
172#endif
173
174
175static void sha256(const uint8_t *buf, int len, uint8_t *h)
176{
177    SHA256_CTX ctx;
178    SHA256_Init(&ctx);
179    SHA256_Update(&ctx, buf, len);
180    SHA256_Final(h, &ctx);
181}
182
183
184/* base on rfc 5869 with sha256, prk is 32 bytes*/
185void lshkdf_extract(const unsigned char *ikm, int ikm_len, const unsigned char *salt,
186                  int salt_len, unsigned char *prk)
187{
188#ifndef NDEBUG
189    unsigned char *out;
190    unsigned int out_len;
191    out =
192#endif
193        HMAC(EVP_sha256(), salt, salt_len, ikm, ikm_len, prk,
194#ifndef NDEBUG
195                                                              &out_len
196#else
197                                                              NULL
198#endif
199                                                                      );
200    assert(out);
201    assert(out_len == 32);
202}
203
204
205#define SHA256LEN   32
206int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_len,
207                uint16_t c_key_len, uint8_t *c_key,
208                uint16_t s_key_len, uint8_t *s_key,
209                uint16_t c_key_iv_len, uint8_t *c_key_iv,
210                uint16_t s_key_iv_len, uint8_t *s_key_iv,
211                uint16_t sub_key_len, uint8_t *sub_key)
212{
213    int L = c_key_len + s_key_len + c_key_iv_len + s_key_iv_len + sub_key_len;
214    int N = (L + SHA256LEN - 1) / SHA256LEN;
215    unsigned char *p_org;
216    uint8_t *buf;
217    unsigned char *p;
218    unsigned char T[SHA256LEN + 1];
219    int T_len = 0;
220    int i;
221    uint8_t *pb;
222
223    p_org = malloc(N * SHA256LEN);
224    if (!p_org)
225        return -1;
226
227    buf = malloc(SHA256LEN + info_len + 13);
228    if (!buf)
229    {
230        free(p_org);
231        return -1;
232    }
233
234    p = p_org;
235
236    for (i = 1; i <= N; ++i)
237    {
238        pb = buf;
239        if (T_len > 0)
240        {
241            memcpy(pb, T, T_len);
242            pb += T_len;
243        }
244
245        memcpy(pb, info, info_len);
246        pb += info_len;
247        *pb = i;
248        ++pb;
249
250        HMAC(EVP_sha256(), prk, SHA256LEN, buf, pb - buf, T, NULL);
251        if (i != N)
252            T_len = SHA256LEN;
253        else
254            T_len = L - (N - 1) * SHA256LEN;
255
256        memcpy(p, T, T_len);
257        p += T_len;
258    }
259
260    free(buf);
261
262    p = p_org;
263    if (c_key_len)
264    {
265        memcpy(c_key, p, c_key_len);
266        p += c_key_len;
267    }
268    if (s_key_len)
269    {
270        memcpy(s_key, p, s_key_len);
271        p += s_key_len;
272    }
273    if (c_key_iv_len)
274    {
275        memcpy(c_key_iv, p, c_key_iv_len);
276        p += c_key_iv_len;
277    }
278    if (s_key_iv_len)
279    {
280        memcpy(s_key_iv, p, s_key_iv_len);
281        p += s_key_iv_len;
282    }
283    if (sub_key_len && sub_key)
284    {
285        memcpy(sub_key, p, sub_key_len);
286        p += sub_key_len;
287    }
288
289    free(p_org);
290    return 0;
291}
292
293
294int export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
295                        unsigned char *salt, int salt_len,
296                        char *label, uint32_t label_len,
297                        const uint8_t *context, uint32_t context_len,
298                        uint8_t *key, uint16_t key_len)
299{
300    unsigned char prk[32];
301    int info_len;
302    uint8_t *info = NULL;
303    info = (uint8_t *)malloc(label_len + 1 + sizeof(uint32_t) + context_len);
304    if (!info)
305        return -1;
306
307    lshkdf_extract(ikm, ikm_len, salt, salt_len, prk);
308    memcpy(info, label, label_len);
309    info[label_len] = 0x00;
310    info_len = label_len + 1;
311    memcpy(info + info_len, &context_len, sizeof(uint32_t));
312    info_len += sizeof(uint32_t);
313    memcpy(info + info_len, context, context_len);
314    info_len += context_len;
315    lshkdf_expand(prk, info, info_len, key_len, key,
316                0, NULL, 0, NULL,0, NULL, 0, NULL);
317    free(info);
318    return 0;
319}
320
321
322int export_key_material(const unsigned char *ikm, uint32_t ikm_len,
323                        const unsigned char *salt, int salt_len,
324                        const unsigned char *context, uint32_t context_len,
325                        uint16_t c_key_len, uint8_t *c_key,
326                        uint16_t s_key_len, uint8_t *s_key,
327                        uint16_t c_key_iv_len, uint8_t *c_key_iv,
328                        uint16_t s_key_iv_len, uint8_t *s_key_iv,
329                        uint8_t *sub_key)
330{
331    unsigned char prk[32];
332    uint16_t sub_key_len = ikm_len;
333
334    lshkdf_extract(ikm, ikm_len, salt, salt_len, prk);
335    lshkdf_expand(prk, context, context_len, c_key_len, c_key,
336                s_key_len, s_key, c_key_iv_len, c_key_iv, s_key_iv_len,
337                s_key_iv, sub_key_len, sub_key);
338    return 0;
339}
340
341void c255_get_pub_key(unsigned char *priv_key, unsigned char pub_key[32])
342{
343    X25519_public_from_private(pub_key, priv_key);
344}
345
346
347int c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, unsigned char *shared_key)
348{
349    return X25519(shared_key, priv_key, peer_pub_key);
350}
351
352
353
354/* AEAD nonce is always zero */
355/* return 0 for OK */
356int aes_aead_enc(EVP_AEAD_CTX *key,
357              const uint8_t *ad, size_t ad_len,
358              const uint8_t *nonce, size_t nonce_len,
359              const uint8_t *plain, size_t plain_len,
360              uint8_t *cypher, size_t *cypher_len)
361{
362    int ret = 0;
363    size_t max_out_len;
364    max_out_len = *cypher_len;//plain_len + EVP_AEAD_max_overhead(aead_);
365    assert(*cypher_len >= max_out_len);
366
367    LSQ_DEBUG("***aes_aead_enc data %s", get_bin_str(plain, plain_len, 40));
368    ret = EVP_AEAD_CTX_seal(key, cypher, cypher_len, max_out_len,
369                            nonce, nonce_len, plain, plain_len, ad, ad_len);
370//     LSQ_DEBUG("***aes_aead_enc nonce: %s", get_bin_str(nonce, nonce_len));
371//     LSQ_DEBUG("***aes_aead_enc AD: %s", get_bin_str(ad, ad_len));
372//     LSQ_DEBUG("***aes_aead_enc return %d", (ret ? 0 : -1));
373    if (ret)
374    {
375        LSQ_DEBUG("***aes_aead_enc succeed, cypher content %s",
376                  get_bin_str(cypher, *cypher_len, 40));
377        return 0;
378    }
379    else
380    {
381        LSQ_DEBUG("***aes_aead_enc failed.");
382        return -1;
383    }
384}
385
386
387/* return 0 for OK */
388int aes_aead_dec(EVP_AEAD_CTX *key,
389              const uint8_t *ad, size_t ad_len,
390              const uint8_t *nonce, size_t nonce_len,
391              const uint8_t *cypher, size_t cypher_len,
392              uint8_t *plain, size_t *plain_len)
393{
394    int ret = 0;
395    size_t max_out_len = *plain_len;
396    assert(max_out_len >= cypher_len);
397
398    LSQ_DEBUG("***aes_aead_dec data %s", get_bin_str(cypher, cypher_len, 40));
399
400
401    ret = EVP_AEAD_CTX_open(key, plain, plain_len, max_out_len,
402                            nonce, nonce_len, cypher, cypher_len, ad, ad_len);
403
404//    LSQ_DEBUG("***aes_aead_dec nonce: %s", get_bin_str(nonce, nonce_len));
405//    LSQ_DEBUG("***aes_aead_dec AD: %s", get_bin_str(ad, ad_len));
406//    LSQ_DEBUG("***aes_aead_dec return %d", (ret ? 0 : -1));
407    if (ret)
408    {
409        LSQ_DEBUG("***aes_aead_dec succeed, plain content %s",
410              get_bin_str(plain, *plain_len, 20));
411        return 0;
412    }
413    else
414    {
415        LSQ_DEBUG("***aes_aead_dec failed.");
416        return -1;
417    }
418}
419
420/* 32 bytes client nonce with 4 bytes tm, 8 bytes orbit */
421void gen_nonce_c(unsigned char *buf, uint64_t orbit)
422{
423    time_t tm = time(NULL);
424    unsigned char *p = buf;
425    memcpy(p, &tm, 4);
426    p += 4;
427    memcpy(p, &orbit, 8);
428    p += 8;
429    rand_bytes(p, 20);
430    p += 20;
431}
432
433
434EVP_PKEY *PEM_to_key(const char *buf, int len)
435{
436    RSA *rsa = NULL;
437    EVP_PKEY *key = EVP_PKEY_new();
438    BIO *bio = BIO_new_mem_buf(buf, len);
439    if (!bio || !key)
440        return NULL;
441
442    rsa = PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL);
443    if (!rsa)
444        return NULL;
445
446    EVP_PKEY_assign_RSA(key, rsa);
447    return key;
448}
449
450
451/* type 0 DER, 1: PEM */
452X509 *bio_to_crt(const void *buf, int len, int type)
453{
454    X509 *crt = NULL;
455    BIO *bio = BIO_new_mem_buf(buf, len);
456    if (bio == NULL)
457        return NULL;
458
459    if (type == 0)
460        crt = d2i_X509_bio(bio, NULL);
461    else
462        crt = PEM_read_bio_X509(bio, &crt, 0 , NULL);
463    BIO_free(bio);
464    return crt;
465}
466
467
468int gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
469             const uint8_t *scfg_data, uint32_t scfg_data_len,
470             const EVP_PKEY *priv_key, uint8_t *buf, size_t *buf_len)
471{
472    uint8_t chlo_hash[32] = {0};
473    size_t chlo_hash_len = 32; /* SHA256 */
474    EVP_MD_CTX sign_context;
475    EVP_PKEY_CTX* pkey_ctx = NULL;
476
477    sha256(chlo_data, chlo_data_len, chlo_hash);
478    EVP_MD_CTX_init(&sign_context);
479    if (!EVP_DigestSignInit(&sign_context, &pkey_ctx, EVP_sha256(), NULL, (EVP_PKEY *)priv_key))
480        return -1;
481
482    EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING);
483    EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1);
484
485    if (!EVP_DigestSignUpdate(&sign_context, s_hs_signature, sizeof(s_hs_signature)) ||
486        !EVP_DigestSignUpdate(&sign_context, (const uint8_t*)(&chlo_hash_len), 4) ||
487        !EVP_DigestSignUpdate(&sign_context, chlo_hash, chlo_hash_len) ||
488        !EVP_DigestSignUpdate(&sign_context, scfg_data, scfg_data_len))
489    {
490        return -1;
491    }
492
493    size_t len = 0;
494    if (!EVP_DigestSignFinal(&sign_context, NULL, &len)) {
495        return -1;
496    }
497
498    if (len > *buf_len)
499        return -2;
500    if (buf)
501        EVP_DigestSignFinal(&sign_context, buf, buf_len);
502
503    EVP_MD_CTX_cleanup(&sign_context);
504    return 0;
505}
506
507
508int verify_prof(const uint8_t *chlo_data, size_t chlo_data_len, lsquic_str_t * scfg,
509                const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
510{
511    return verify_prof0(chlo_data, chlo_data_len,
512                        (const uint8_t *)lsquic_str_buf(scfg),
513                        lsquic_str_len(scfg), pub_key, buf, len);
514}
515
516
517
518
519/* -3 internal error, -1: verify failed, 0: Success */
520int verify_prof0(const uint8_t *chlo_data, size_t chlo_data_len,
521                const uint8_t *scfg_data, uint32_t scfg_data_len,
522                const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
523{
524    uint8_t chlo_hash[32] = {0};
525    size_t chlo_hash_len = 32; /* SHA256 */
526    EVP_MD_CTX sign_context;
527    EVP_PKEY_CTX* pkey_ctx = NULL;
528    int ret = 0;
529    EVP_MD_CTX_init(&sign_context);
530    sha256(chlo_data, chlo_data_len, chlo_hash);
531
532    // discarding const below to quiet compiler warning on call to ssl library code
533    if (!EVP_DigestVerifyInit(&sign_context, &pkey_ctx, EVP_sha256(), NULL, (EVP_PKEY *)pub_key))
534        return -4;
535
536    EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING);
537    EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1);
538
539
540    if (!EVP_DigestVerifyUpdate(&sign_context, s_hs_signature, sizeof(s_hs_signature)) ||
541        !EVP_DigestVerifyUpdate(&sign_context, (const uint8_t*)(&chlo_hash_len), 4) ||
542        !EVP_DigestVerifyUpdate(&sign_context, chlo_hash, chlo_hash_len) ||
543        !EVP_DigestVerifyUpdate(&sign_context, scfg_data, scfg_data_len))
544    {
545        return -3;  /* set to -3, to avoid same as "not enough data" -2 */
546    }
547
548    ret = EVP_DigestVerifyFinal(&sign_context, buf, len);
549    EVP_MD_CTX_cleanup(&sign_context);
550
551    if (ret == 1)
552        return 0; //OK
553    else
554        return -1;  //failed
555}
556
557
558void crypto_init(void)
559{
560    if (crypto_inited)
561        return ;
562
563    //SSL_library_init();
564    CRYPTO_library_init();
565    /* XXX Should we seed? If yes, wherewith? */ // RAND_seed(seed, seed_len);
566
567#if defined( __x86_64 )||defined( __x86_64__ )
568    make_uint128(&s_prime, 16777216, 315);
569    make_uint128(&s_init_hash, 7809847782465536322, 7113472399480571277);
570#endif
571
572    /* MORE .... */
573    crypto_inited = 1;
574}
575
576