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