summaryrefslogtreecommitdiff
path: root/lib/vquic/ngtcp2-crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vquic/ngtcp2-crypto.c')
-rw-r--r--lib/vquic/ngtcp2-crypto.c511
1 files changed, 0 insertions, 511 deletions
diff --git a/lib/vquic/ngtcp2-crypto.c b/lib/vquic/ngtcp2-crypto.c
deleted file mode 100644
index 887c130cb..000000000
--- a/lib/vquic/ngtcp2-crypto.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#ifdef USE_NGTCP2
-#include <ngtcp2/ngtcp2.h>
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#include <openssl/kdf.h>
-#include "ngtcp2-crypto.h"
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-
-static int hkdf_expand_label(uint8_t *dest, size_t destlen,
- const uint8_t *secret, size_t secretlen,
- const uint8_t *label, size_t labellen,
- const struct Context *ctx);
-
-void Curl_qc_prf_sha256(struct Context *ctx)
-{
- ctx->prf = EVP_sha256();
-}
-
-void Curl_qc_aead_aes_128_gcm(struct Context *ctx)
-{
- ctx->aead = EVP_aes_128_gcm();
- ctx->hp = EVP_aes_128_ctr();
-}
-
-size_t Curl_qc_aead_nonce_length(const struct Context *ctx)
-{
- return EVP_CIPHER_iv_length(ctx->aead);
-}
-
-
-int Curl_qc_negotiated_prf(struct Context *ctx, SSL *ssl)
-{
- switch(SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
- case 0x03001301u: /* TLS_AES_128_GCM_SHA256 */
- case 0x03001303u: /* TLS_CHACHA20_POLY1305_SHA256 */
- case 0x03001304u: /* TLS_AES_128_CCM_SHA256 */
- ctx->prf = EVP_sha256();
- return 0;
- case 0x03001302u: /* TLS_AES_256_GCM_SHA384 */
- ctx->prf = EVP_sha384();
- return 0;
- default:
- return -1;
- }
-}
-
-int Curl_qc_negotiated_aead(struct Context *ctx, SSL *ssl)
-{
- switch(SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
- case 0x03001301u: /* TLS_AES_128_GCM_SHA256 */
- ctx->aead = EVP_aes_128_gcm();
- ctx->hp = EVP_aes_128_ctr();
- return 0;
- case 0x03001302u: /* TLS_AES_256_GCM_SHA384 */
- ctx->aead = EVP_aes_256_gcm();
- ctx->hp = EVP_aes_256_ctr();
- return 0;
- case 0x03001303u: /* TLS_CHACHA20_POLY1305_SHA256 */
- ctx->aead = EVP_chacha20_poly1305();
- ctx->hp = EVP_chacha20();
- return 0;
- case 0x03001304u: /* TLS_AES_128_CCM_SHA256 */
- ctx->aead = EVP_aes_128_ccm();
- ctx->hp = EVP_aes_128_ctr();
- return 0;
- default:
- return -1;
- }
-}
-
-ssize_t Curl_qc_encrypt_pn(uint8_t *dest, size_t destlen,
- const uint8_t *plaintext, size_t plaintextlen,
- const struct Context *ctx,
- const uint8_t *key, size_t keylen,
- const uint8_t *nonce, size_t noncelen)
-{
- EVP_CIPHER_CTX *actx = EVP_CIPHER_CTX_new();
- size_t outlen = 0;
- int len;
- (void)destlen;
- (void)keylen;
- (void)noncelen;
-
- if(!actx)
- return -1;
-
- if(EVP_EncryptInit_ex(actx, ctx->hp, NULL, key, nonce) != 1)
- goto error;
-
- if(EVP_EncryptUpdate(actx, dest, &len, plaintext, (int)plaintextlen) != 1)
- goto error;
-
- assert(len > 0);
-
- outlen = len;
-
- if(EVP_EncryptFinal_ex(actx, dest + outlen, &len) != 1)
- goto error;
-
- assert(len == 0);
- /* outlen += len; */
-
- EVP_CIPHER_CTX_free(actx);
- return outlen;
-
- error:
- EVP_CIPHER_CTX_free(actx);
- return -1;
-}
-
-static int hkdf_expand(uint8_t *dest, size_t destlen, const uint8_t *secret,
- size_t secretlen, const uint8_t *info, size_t infolen,
- const struct Context *ctx)
-{
- void *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
- if(!pctx)
- return -1;
-
- if(EVP_PKEY_derive_init(pctx) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_set_hkdf_md(pctx, ctx->prf) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_set1_hkdf_salt(pctx, "", 0) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)secretlen) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_add1_hkdf_info(pctx, info, (int)infolen) != 1)
- goto err;
-
- if(EVP_PKEY_derive(pctx, dest, &destlen) != 1)
- goto err;
-
- return 0;
- err:
- EVP_PKEY_CTX_free(pctx);
- return -1;
-}
-
-static int hkdf_extract(uint8_t *dest, size_t destlen,
- const uint8_t *secret, size_t secretlen,
- const uint8_t *salt, size_t saltlen,
- const struct Context *ctx)
-{
- void *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
- if(!pctx)
- return -1;
-
- if(EVP_PKEY_derive_init(pctx) != 1)
- goto err;
-
- if(EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) != 1) {
- goto err;
- }
-
- if(EVP_PKEY_CTX_set_hkdf_md(pctx, ctx->prf) != 1) {
- goto err;
- }
-
- if(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, (int)saltlen) != 1) {
- goto err;
- }
-
- if(EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)secretlen) != 1) {
- goto err;
- }
-
- if(EVP_PKEY_derive(pctx, dest, &destlen) != 1) {
- goto err;
- }
-
- EVP_PKEY_CTX_free(pctx);
- return 0;
- err:
- EVP_PKEY_CTX_free(pctx);
- return -1;
-}
-
-static size_t aead_key_length(const struct Context *ctx)
-{
- return EVP_CIPHER_key_length(ctx->aead);
-}
-
-static size_t aead_tag_length(const struct Context *ctx)
-{
- if(ctx->aead == EVP_aes_128_gcm() || ctx->aead == EVP_aes_256_gcm()) {
- return EVP_GCM_TLS_TAG_LEN;
- }
- if(ctx->aead == EVP_chacha20_poly1305()) {
- return EVP_CHACHAPOLY_TLS_TAG_LEN;
- }
- if(ctx->aead == EVP_aes_128_ccm())
- return EVP_CCM_TLS_TAG_LEN;
- assert(0);
-}
-
-size_t Curl_qc_aead_max_overhead(const struct Context *ctx)
-{
- return aead_tag_length(ctx);
-}
-
-int Curl_qc_encrypt(uint8_t *dest,
- const uint8_t *plaintext, size_t plaintextlen,
- const struct Context *ctx,
- const uint8_t *key,
- const uint8_t *nonce, size_t noncelen,
- const uint8_t *ad, size_t adlen)
-{
- size_t taglen = aead_tag_length(ctx);
- EVP_CIPHER_CTX *actx;
- int outlen = 0;
- int len;
-
- actx = EVP_CIPHER_CTX_new();
- if(!actx)
- return -1;
-
- if(EVP_EncryptInit_ex(actx, ctx->aead, NULL, NULL, NULL) != 1)
- goto error;
-
- if(EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_IVLEN,
- (int)noncelen, NULL) != 1)
- goto error;
-
- if(ctx->aead == EVP_aes_128_ccm() &&
- EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG, (int)taglen, NULL) != 1)
- goto error;
-
- if(EVP_EncryptInit_ex(actx, NULL, NULL, key, nonce) != 1)
- goto error;
-
- if(ctx->aead == EVP_aes_128_ccm() &&
- EVP_EncryptUpdate(actx, NULL, &len, NULL, (int)plaintextlen) != 1)
- goto error;
-
- if(EVP_EncryptUpdate(actx, NULL, &len, ad, (int)adlen) != 1)
- goto error;
-
- if(EVP_EncryptUpdate(actx, dest, &len, plaintext, (int)plaintextlen) != 1)
- goto error;
-
- outlen = len;
- if(EVP_EncryptFinal_ex(actx, dest + outlen, &len) != 1)
- goto error;
-
- if(EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_GET_TAG,
- (int)taglen, dest + outlen) != 1)
- goto error;
-
- EVP_CIPHER_CTX_free(actx);
- return 0;
-
- error:
- EVP_CIPHER_CTX_free(actx);
- return -1;
-}
-
-int Curl_qc_decrypt(uint8_t *dest,
- const uint8_t *ciphertext, size_t ciphertextlen,
- const struct Context *ctx,
- const uint8_t *key,
- const uint8_t *nonce, size_t noncelen,
- const uint8_t *ad, size_t adlen)
-{
- size_t taglen = aead_tag_length(ctx);
- const uint8_t *tag;
- EVP_CIPHER_CTX *actx;
- int outlen;
- int len;
-
- if(taglen > ciphertextlen)
- return -1;
-
- ciphertextlen -= taglen;
- tag = ciphertext + ciphertextlen;
-
- actx = EVP_CIPHER_CTX_new();
- if(!actx)
- return -1;
-
- if(EVP_DecryptInit_ex(actx, ctx->aead, NULL, NULL, NULL) != 1)
- goto error;
-
- if(EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_IVLEN, (int)noncelen, NULL) !=
- 1)
- goto error;
-
- if(ctx->aead == EVP_aes_128_ccm() &&
- EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG, (int)taglen,
- (uint8_t *)tag) != 1)
- goto error;
-
- if(EVP_DecryptInit_ex(actx, NULL, NULL, key, nonce) != 1)
- goto error;
-
- if(ctx->aead == EVP_aes_128_ccm() &&
- EVP_DecryptUpdate(actx, NULL, &len, NULL, (int)ciphertextlen) != 1)
- goto error;
-
- if(EVP_DecryptUpdate(actx, NULL, &len, ad, (int)adlen) != 1)
- goto error;
-
- if(EVP_DecryptUpdate(actx, dest, &len, ciphertext, (int)ciphertextlen) != 1)
- goto error;
-
- outlen = len;
-
- if(ctx->aead == EVP_aes_128_ccm())
- return 0;
-
- if(EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG,
- (int)taglen, (char *)tag) != 1)
- goto error;
-
- if(EVP_DecryptFinal_ex(actx, dest + outlen, &len) != 1)
- goto error;
-
- EVP_CIPHER_CTX_free(actx);
- return 0;
- error:
- EVP_CIPHER_CTX_free(actx);
- return -1;
-}
-
-int Curl_qc_derive_initial_secret(uint8_t *dest, size_t destlen,
- const ngtcp2_cid *secret,
- const uint8_t *salt,
- size_t saltlen)
-{
- struct Context ctx;
- Curl_qc_prf_sha256(&ctx);
- return hkdf_extract(dest, destlen, secret->data, secret->datalen, salt,
- saltlen, &ctx);
-}
-
-int Curl_qc_derive_client_initial_secret(uint8_t *dest,
- size_t destlen,
- const uint8_t *secret,
- size_t secretlen)
-{
- static uint8_t LABEL[] = "client in";
- struct Context ctx;
- Curl_qc_prf_sha256(&ctx);
- return hkdf_expand_label(dest, destlen, secret, secretlen, LABEL,
- sizeof(LABEL) - 1, &ctx);
-}
-
-ssize_t Curl_qc_derive_packet_protection_key(uint8_t *dest, size_t destlen,
- const uint8_t *secret,
- size_t secretlen,
- const struct Context *ctx)
-{
- int rv;
- static uint8_t LABEL[] = "quic key";
- size_t keylen = aead_key_length(ctx);
- if(keylen > destlen) {
- return -1;
- }
-
- rv = hkdf_expand_label(dest, keylen, secret, secretlen, LABEL,
- sizeof(LABEL) - 1, ctx);
- if(rv) {
- return -1;
- }
-
- return keylen;
-}
-
-ssize_t Curl_qc_derive_packet_protection_iv(uint8_t *dest, size_t destlen,
- const uint8_t *secret,
- size_t secretlen,
- const struct Context *ctx)
-{
- int rv;
- static uint8_t LABEL[] = "quic iv";
-
- size_t ivlen = CURLMAX(8, Curl_qc_aead_nonce_length(ctx));
- if(ivlen > destlen) {
- return -1;
- }
-
- rv = hkdf_expand_label(dest, ivlen, secret, secretlen, LABEL,
- sizeof(LABEL) - 1, ctx);
- if(rv) {
- return -1;
- }
-
- return ivlen;
-}
-
-int Curl_qc_derive_server_initial_secret(uint8_t *dest, size_t destlen,
- const uint8_t *secret,
- size_t secretlen)
-{
- static uint8_t LABEL[] = "server in";
- struct Context ctx;
- Curl_qc_prf_sha256(&ctx);
- return hkdf_expand_label(dest, destlen, secret, secretlen, LABEL,
- sizeof(LABEL) - 1, &ctx);
-}
-
-static int
-hkdf_expand_label(uint8_t *dest, size_t destlen, const uint8_t *secret,
- size_t secretlen, const uint8_t *label, size_t labellen,
- const struct Context *ctx)
-{
- uint8_t info[256];
- static const uint8_t LABEL[] = "tls13 ";
-
- uint8_t *p = &info[0];
- *p++ = (destlen / 256)&0xff;
- *p++ = destlen % 256;
- *p++ = (sizeof(LABEL) - 1 + labellen) & 0xff;
- memcpy(p, LABEL, sizeof(LABEL) - 1);
- p += sizeof(LABEL) - 1;
- memcpy(p, label, labellen);
- p += labellen;
- *p++ = 0;
-
- return hkdf_expand(dest, destlen, secret, secretlen, &info[0],
- p - &info[0], ctx);
-}
-
-ssize_t
-Curl_qc_derive_header_protection_key(uint8_t *dest, size_t destlen,
- const uint8_t *secret, size_t secretlen,
- const struct Context *ctx)
-{
- int rv;
- static uint8_t LABEL[] = "quic hp";
-
- size_t keylen = aead_key_length(ctx);
- if(keylen > destlen)
- return -1;
-
- rv = hkdf_expand_label(dest, keylen, secret, secretlen, LABEL,
- sizeof(LABEL) - 1, ctx);
-
- if(rv)
- return -1;
-
- return keylen;
-}
-
-int Curl_qc_hp_mask(uint8_t *dest, const struct Context *ctx,
- const uint8_t *key, const uint8_t *sample)
-{
- static uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
- EVP_CIPHER_CTX *actx;
- int outlen = 0;
- int len;
- actx = EVP_CIPHER_CTX_new();
- if(!actx)
- return -1;
-
- if(EVP_EncryptInit_ex(actx, ctx->hp, NULL, key, sample) != 1)
- goto error;
- if(EVP_EncryptUpdate(actx, dest, &len, PLAINTEXT,
- (int)(sizeof(PLAINTEXT) - 1)) != 1)
- goto error;
-
- DEBUGASSERT(len == 5);
-
- outlen = len;
-
- if(EVP_EncryptFinal_ex(actx, dest + outlen, &len) != 1)
- goto error;
-
- DEBUGASSERT(len == 0);
-
- return 0;
- error:
- EVP_CIPHER_CTX_free(actx);
- return -1;
-}
-
-
-#endif