diff --git a/linux-4.14.32.patch b/linux-4.14.32.patch index 8c77a0e5e..5966da28f 100644 --- a/linux-4.14.32.patch +++ b/linux-4.14.32.patch @@ -114,8 +114,63 @@ index f92a6593..d27c08f4 100644 } EXPORT_SYMBOL_GPL(kernel_fpu_end); +diff --git a/crypto/aead.c b/crypto/aead.c +index f794b30a..b6c3062b 100644 +--- a/crypto/aead.c ++++ b/crypto/aead.c +@@ -343,6 +343,22 @@ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask) + } + EXPORT_SYMBOL_GPL(crypto_alloc_aead); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg * ++crypto_find_aead(const char *alg_name, u32 type, u32 mask) ++{ ++ return crypto_find_alg(alg_name, &crypto_aead_type, type, mask); ++} ++EXPORT_SYMBOL_GPL(crypto_find_aead); ++ ++struct crypto_aead * ++crypto_alloc_aead_atomic(struct crypto_alg *alg) ++{ ++ return crypto_create_tfm(alg, &crypto_aead_type); ++} ++EXPORT_SYMBOL_GPL(crypto_alloc_aead_atomic); ++#endif ++ + static int aead_prepare_alg(struct aead_alg *alg) + { + struct crypto_alg *base = &alg->base; +diff --git a/crypto/ahash.c b/crypto/ahash.c +index f75b5c1f..9d659002 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -559,6 +559,23 @@ struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, + } + EXPORT_SYMBOL_GPL(crypto_alloc_ahash); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++/* Asynch hash is required by GHASH used in GCM. */ ++struct crypto_alg * ++crypto_find_ahash(const char *alg_name, u32 type, u32 mask) ++{ ++ return crypto_find_alg(alg_name, &crypto_ahash_type, type, mask); ++} ++EXPORT_SYMBOL_GPL(crypto_find_ahash); ++ ++struct crypto_ahash * ++crypto_alloc_ahash_atomic(struct crypto_alg *alg) ++{ ++ return crypto_create_tfm(alg, &crypto_ahash_type); ++} ++EXPORT_SYMBOL_GPL(crypto_alloc_ahash_atomic); ++#endif ++ + int crypto_has_ahash(const char *alg_name, u32 type, u32 mask) + { + return crypto_type_has_alg(alg_name, &crypto_ahash_type, type, mask); diff --git a/crypto/api.c b/crypto/api.c -index 941cd4c6..5fd308d8 100644 +index 941cd4c6..77dab1fd 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -451,7 +451,11 @@ void *crypto_create_tfm(struct crypto_alg *alg, @@ -130,6 +185,226 @@ index 941cd4c6..5fd308d8 100644 if (mem == NULL) goto out_err; +@@ -487,6 +491,9 @@ struct crypto_alg *crypto_find_alg(const char *alg_name, + struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask) = + crypto_alg_mod_lookup; + ++ /* The function is slow and preemptable to be called in softirq. */ ++ WARN_ON_ONCE(in_serving_softirq()); ++ + if (frontend) { + type &= frontend->maskclear; + mask &= frontend->maskclear; +diff --git a/crypto/cryptd.c b/crypto/cryptd.c +index 248f6ba4..3fe4f2c1 100644 +--- a/crypto/cryptd.c ++++ b/crypto/cryptd.c +@@ -1217,12 +1217,29 @@ struct cryptd_skcipher *cryptd_alloc_skcipher(const char *alg_name, + char cryptd_alg_name[CRYPTO_MAX_ALG_NAME]; + struct cryptd_skcipher_ctx *ctx; + struct crypto_skcipher *tfm; +- ++#ifdef CONFIG_SECURITY_TEMPESTA ++ static struct crypto_alg *alg = NULL; ++ ++ if (unlikely(!alg)) { ++ WARN_ON_ONCE(in_serving_softirq()); ++ if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, "cryptd(%s)", ++ alg_name) ++ >= CRYPTO_MAX_ALG_NAME) ++ { ++ return ERR_PTR(-EINVAL); ++ } ++ alg = crypto_find_skcipher(cryptd_alg_name, type, mask); ++ if (IS_ERR(alg)) ++ return (struct cryptd_skcipher *)alg; ++ } ++ tfm = crypto_alloc_skcipher_atomic(alg); ++#else + if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, + "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME) + return ERR_PTR(-EINVAL); + + tfm = crypto_alloc_skcipher(cryptd_alg_name, type, mask); ++#endif + if (IS_ERR(tfm)) + return ERR_CAST(tfm); + +@@ -1269,11 +1286,28 @@ struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name, + char cryptd_alg_name[CRYPTO_MAX_ALG_NAME]; + struct cryptd_hash_ctx *ctx; + struct crypto_ahash *tfm; +- ++#ifdef CONFIG_SECURITY_TEMPESTA ++ static struct crypto_alg *alg = NULL; ++ ++ if (unlikely(!alg)) { ++ WARN_ON_ONCE(in_serving_softirq()); ++ if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, "cryptd(%s)", ++ alg_name) ++ >= CRYPTO_MAX_ALG_NAME) ++ { ++ return ERR_PTR(-EINVAL); ++ } ++ alg = crypto_find_ahash(cryptd_alg_name, type, mask); ++ if (IS_ERR(alg)) ++ return (struct cryptd_ahash *)alg; ++ } ++ tfm = crypto_alloc_ahash_atomic(alg); ++#else + if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, + "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME) + return ERR_PTR(-EINVAL); + tfm = crypto_alloc_ahash(cryptd_alg_name, type, mask); ++#endif + if (IS_ERR(tfm)) + return ERR_CAST(tfm); + if (tfm->base.__crt_alg->cra_module != THIS_MODULE) { +@@ -1326,11 +1360,28 @@ struct cryptd_aead *cryptd_alloc_aead(const char *alg_name, + char cryptd_alg_name[CRYPTO_MAX_ALG_NAME]; + struct cryptd_aead_ctx *ctx; + struct crypto_aead *tfm; +- ++#ifdef CONFIG_SECURITY_TEMPESTA ++ static struct crypto_alg *alg = NULL; ++ ++ if (unlikely(!alg)) { ++ WARN_ON_ONCE(in_serving_softirq()); ++ if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, "cryptd(%s)", ++ alg_name) ++ >= CRYPTO_MAX_ALG_NAME) ++ { ++ return ERR_PTR(-EINVAL); ++ } ++ alg = crypto_find_aead(cryptd_alg_name, type, mask); ++ if (IS_ERR(alg)) ++ return (struct cryptd_aead *)alg; ++ } ++ tfm = crypto_alloc_aead_atomic(alg); ++#else + if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, + "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME) + return ERR_PTR(-EINVAL); + tfm = crypto_alloc_aead(cryptd_alg_name, type, mask); ++#endif + if (IS_ERR(tfm)) + return ERR_CAST(tfm); + if (tfm->base.__crt_alg->cra_module != THIS_MODULE) { +diff --git a/crypto/shash.c b/crypto/shash.c +index 5d732c6b..f3f35aba 100644 +--- a/crypto/shash.c ++++ b/crypto/shash.c +@@ -454,6 +454,22 @@ struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, + } + EXPORT_SYMBOL_GPL(crypto_alloc_shash); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg * ++crypto_find_shash(const char *alg_name, u32 type, u32 mask) ++{ ++ return crypto_find_alg(alg_name, &crypto_shash_type, type, mask); ++} ++EXPORT_SYMBOL_GPL(crypto_find_shash); ++ ++struct crypto_shash * ++crypto_alloc_shash_atomic(struct crypto_alg *alg) ++{ ++ return crypto_create_tfm(alg, &crypto_shash_type); ++} ++EXPORT_SYMBOL_GPL(crypto_alloc_shash_atomic); ++#endif ++ + static int shash_prepare_alg(struct shash_alg *alg) + { + struct crypto_alg *base = &alg->base; +diff --git a/crypto/skcipher.c b/crypto/skcipher.c +index 11af5fd6..f45933b6 100644 +--- a/crypto/skcipher.c ++++ b/crypto/skcipher.c +@@ -928,6 +928,22 @@ struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, + } + EXPORT_SYMBOL_GPL(crypto_alloc_skcipher); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg * ++crypto_find_skcipher(const char *alg_name, u32 type, u32 mask) ++{ ++ return crypto_find_alg(alg_name, &crypto_skcipher_type2, type, mask); ++} ++EXPORT_SYMBOL_GPL(crypto_find_skcipher); ++ ++struct crypto_skcipher * ++crypto_alloc_skcipher_atomic(struct crypto_alg *alg) ++{ ++ return crypto_create_tfm(alg, &crypto_skcipher_type2); ++} ++EXPORT_SYMBOL_GPL(crypto_alloc_skcipher_atomic); ++#endif ++ + int crypto_has_skcipher2(const char *alg_name, u32 type, u32 mask) + { + return crypto_type_has_alg(alg_name, &crypto_skcipher_type2, +diff --git a/include/crypto/aead.h b/include/crypto/aead.h +index 03b97629..1089ee66 100644 +--- a/include/crypto/aead.h ++++ b/include/crypto/aead.h +@@ -179,6 +179,11 @@ static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) + */ + struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg *crypto_find_aead(const char *alg_name, u32 type, u32 mask); ++struct crypto_aead *crypto_alloc_aead_atomic(struct crypto_alg *alg); ++#endif ++ + static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) + { + return &tfm->base; +diff --git a/include/crypto/hash.h b/include/crypto/hash.h +index 74827781..6fc97be4 100644 +--- a/include/crypto/hash.h ++++ b/include/crypto/hash.h +@@ -245,6 +245,11 @@ static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) + struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, + u32 mask); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg *crypto_find_ahash(const char *alg_name, u32 type, u32 mask); ++struct crypto_ahash *crypto_alloc_ahash_atomic(struct crypto_alg *alg); ++#endif ++ + static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) + { + return &tfm->base; +@@ -681,6 +686,11 @@ static inline void ahash_request_set_crypt(struct ahash_request *req, + struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, + u32 mask); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg *crypto_find_shash(const char *alg_name, u32 type, u32 mask); ++struct crypto_shash *crypto_alloc_shash_atomic(struct crypto_alg *alg); ++#endif ++ + static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) + { + return &tfm->base; +diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h +index 562001cb..b99ea7bb 100644 +--- a/include/crypto/skcipher.h ++++ b/include/crypto/skcipher.h +@@ -197,6 +197,12 @@ static inline struct crypto_skcipher *__crypto_skcipher_cast( + struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, + u32 type, u32 mask); + ++#ifdef CONFIG_SECURITY_TEMPESTA ++struct crypto_alg *crypto_find_skcipher(const char *alg_name, u32 type, ++ u32 mask); ++struct crypto_skcipher *crypto_alloc_skcipher_atomic(struct crypto_alg *alg); ++#endif ++ + static inline struct crypto_tfm *crypto_skcipher_tfm( + struct crypto_skcipher *tfm) + { diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 69c23821..58486beb 100644 --- a/include/linux/interrupt.h @@ -469,18 +744,17 @@ index d323d4fa..0f6bd0cf 100644 } diff --git a/include/net/tls.h b/include/net/tls.h -index df950383..4a99f03d 100644 +index df950383..c3d45c5e 100644 --- a/include/net/tls.h +++ b/include/net/tls.h -@@ -55,6 +55,13 @@ +@@ -55,6 +55,12 @@ #define TLS_AAD_SPACE_SIZE 13 +#ifdef CONFIG_SECURITY_TEMPESTA +#define TLS_MAX_TAG_SZ 16 +/* Maximum size for required skb overhead: header, IV, tag. */ -+#define TLS_MAX_OVERHEAD (TLS_HEADER_SIZE + TLS_AAD_SPACE_SIZE \ -+ + TLS_MAX_TAG_SZ) ++#define TLS_MAX_OVERHEAD (TLS_AAD_SPACE_SIZE + TLS_MAX_TAG_SZ) +#endif + struct tls_sw_context { diff --git a/tempesta_fw/tls.c b/tempesta_fw/tls.c index da6b591c9..4876781c5 100644 --- a/tempesta_fw/tls.c +++ b/tempesta_fw/tls.c @@ -250,7 +250,8 @@ tfw_tls_encrypt(struct sock *sk, struct sk_buff *skb, unsigned int limit) tcb->seq, tcb->end_seq); BUG_ON(!ttls_xfrm_ready(tls)); WARN_ON_ONCE(skb->len > TLS_MAX_PAYLOAD_SIZE); - WARN_ON_ONCE(tcb->seq + skb->len != tcb->end_seq); + WARN_ON_ONCE(tcb->seq + skb->len + !!(tcb->tcp_flags & TCPHDR_FIN) + != tcb->end_seq); head_sz = ttls_payload_off(xfrm); tag_sz = ttls_xfrm_taglen(xfrm); diff --git a/tls/bignum.c b/tls/bignum.c index b2ecf5477..fb81f2a31 100644 --- a/tls/bignum.c +++ b/tls/bignum.c @@ -2169,7 +2169,7 @@ ttls_mpi_modexit(void) } } -int +int __init ttls_mpi_modinit(void) { int cpu; diff --git a/tls/cipher.c b/tls/cipher.c deleted file mode 100644 index 23f78e972..000000000 --- a/tls/cipher.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Tempesta TLS - * - * Generic cipher wrapper. - * - * Author Adriaan de Jong - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include -#include - -#include "lib/str.h" -#include "config.h" -#include "cipher.h" -#include "debug.h" - -typedef struct { - ttls_cipher_type_t type; - const ttls_cipher_info_t *info; -} TlsCipherDef; - -extern const TlsCipherDef ttls_cipher_definitions[]; - -static struct crypto_aead * -gcm_aes_ctx_alloc(void) -{ - struct crypto_aead *a = crypto_alloc_aead("gcm(aes)", 0, 0); - - if (IS_ERR(a)) - T_ERR("cannot initialize gcm(aes) cipher." - " Please check /proc/crypto for the algorithm\n"); - - return a; -} - -static struct crypto_aead * -ccm_aes_ctx_alloc(void) -{ - struct crypto_aead *a = crypto_alloc_aead("ccm(aes)", 0, 0); - - if (IS_ERR(a)) - T_ERR("cannot initialize ccm(aes) cipher." - " Please check /proc/crypto for the algorithm\n"); - - return a; -} - -const ttls_cipher_info_t * -ttls_cipher_info_from_type(const ttls_cipher_type_t cipher_type) -{ - const TlsCipherDef *def; - - for (def = ttls_cipher_definitions; def->info; def++) - if (def->type == cipher_type) - return def->info; - return NULL; -} - -void -ttls_cipher_free(TlsCipherCtx *ctx) -{ - if (!ctx) - return; - - if (ctx->cipher_ctx) - ctx->cipher_info->base->ctx_free_func(ctx->cipher_ctx); - - bzero_fast(ctx, sizeof(TlsCipherCtx)); -} - -int -ttls_cipher_setup(TlsCipherCtx *ctx, const ttls_cipher_info_t *ci, - unsigned int tag_size) -{ - int r; - - BUG_ON(!ci || !ctx); - - bzero_fast(ctx, sizeof(TlsCipherCtx)); - - if (!(ctx->cipher_ctx = ci->base->ctx_alloc_func())) - return TTLS_ERR_CIPHER_ALLOC_FAILED; - if ((r = crypto_aead_setauthsize(ctx->cipher_ctx, tag_size))) { - ttls_cipher_free(ctx); - return r; - } - - /* See IV definitions for all cipher suites at the below. */ - WARN_ON_ONCE(crypto_aead_ivsize(ctx->cipher_ctx) != 12); - - ctx->cipher_info = ci; - - return 0; -} - -static ttls_cipher_base_t gcm_aes_info = { - .cipher = TTLS_CIPHER_ID_AES, - .ctx_alloc_func = gcm_aes_ctx_alloc, - .ctx_free_func = crypto_free_aead, -}; - -static const ttls_cipher_info_t aes_128_gcm_info = { - TTLS_CIPHER_AES_128_GCM, - TTLS_MODE_GCM, - 16, - "AES-128-GCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const ttls_cipher_info_t aes_192_gcm_info = { - TTLS_CIPHER_AES_192_GCM, - TTLS_MODE_GCM, - 24, - "AES-192-GCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const ttls_cipher_info_t aes_256_gcm_info = { - TTLS_CIPHER_AES_256_GCM, - TTLS_MODE_GCM, - 32, - "AES-256-GCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static ttls_cipher_base_t ccm_aes_info = { - .cipher = TTLS_CIPHER_ID_AES, - .ctx_alloc_func = ccm_aes_ctx_alloc, - .ctx_free_func = crypto_free_aead, -}; - -static const ttls_cipher_info_t aes_128_ccm_info = { - TTLS_CIPHER_AES_128_CCM, - TTLS_MODE_CCM, - 16, - "AES-128-CCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const ttls_cipher_info_t aes_192_ccm_info = { - TTLS_CIPHER_AES_192_CCM, - TTLS_MODE_CCM, - 24, - "AES-192-CCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const ttls_cipher_info_t aes_256_ccm_info = { - TTLS_CIPHER_AES_256_CCM, - TTLS_MODE_CCM, - 32, - "AES-256-CCM", - 12, - TTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -const TlsCipherDef ttls_cipher_definitions[] = -{ - { TTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, - { TTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { TTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, - { TTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, - { TTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { TTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, - { TTLS_CIPHER_NONE, NULL } -}; diff --git a/tls/cipher.h b/tls/cipher.h deleted file mode 100644 index f8b0f146a..000000000 --- a/tls/cipher.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Tempesta TLS - * - * The generic cipher wrapper. - * - * Adriaan de Jong - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef TTLS_CIPHER_H -#define TTLS_CIPHER_H - -#include "config.h" - -/**< The selected feature is not available. */ -#define TTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 -/**< Bad input parameters. */ -#define TTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 -/**< Failed to allocate memory. */ -#define TTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 -/**< Input data contains invalid padding and is rejected. */ -#define TTLS_ERR_CIPHER_INVALID_PADDING -0x6200 -/**< Decryption of block requires a full block. */ -#define TTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 -/**< Authentication failed (for AEAD modes). */ -#define TTLS_ERR_CIPHER_AUTH_FAILED -0x6300 -/**< The context is invalid. For example, because it was freed. */ -#define TTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 -/**< Cipher hardware accelerator failed. */ -#define TTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 - -/**< Cipher accepts IVs of variable length. */ -#define TTLS_CIPHER_VARIABLE_IV_LEN 0x01 -/**< Cipher accepts keys of variable length. */ -#define TTLS_CIPHER_VARIABLE_KEY_LEN 0x02 - -/* An enumeration of supported ciphers. */ -typedef enum { - TTLS_CIPHER_ID_NONE = 0, - TTLS_CIPHER_ID_AES, -} ttls_cipher_id_t; - -/* Supported (cipher, mode) pairs. */ -typedef enum { - TTLS_CIPHER_NONE = 0, - TTLS_CIPHER_AES_128_GCM, - TTLS_CIPHER_AES_192_GCM, - TTLS_CIPHER_AES_256_GCM, - TTLS_CIPHER_AES_128_CCM, - TTLS_CIPHER_AES_192_CCM, - TTLS_CIPHER_AES_256_CCM, -} ttls_cipher_type_t; - -/* Supported cipher modes. */ -typedef enum { - TTLS_MODE_NONE = 0, - TTLS_MODE_GCM, - TTLS_MODE_STREAM, /* TLS 1.3: ChaCha20-Poly1305 */ - TTLS_MODE_CCM, -} ttls_cipher_mode_t; - -/* Supported cipher padding types. */ -typedef enum { - TTLS_PADDING_PKCS7 = 0, /* PKCS7 padding (default) */ - TTLS_PADDING_ONE_AND_ZEROS, /* ISO/IEC 7816-4 padding */ - TTLS_PADDING_ZEROS_AND_LEN, /* ANSI X.923 padding */ - TTLS_PADDING_ZEROS, /* zero padding (not reversible) */ - TTLS_PADDING_NONE, /* never pad (full blocks only) */ -} ttls_cipher_padding_t; - -/** Maximum length of any IV, in Bytes. */ -#define TTLS_MAX_IV_LENGTH 16 - -/** - * Base cipher information. The non-mode specific functions and values. - * - * @cipher - Base Cipher type (e.g. TTLS_CIPHER_ID_AES); - * @stream_func - Encrypt using STREAM; - * @ctx_alloc_func - Allocate a new context; - * @ctx_free_func - Free the given context; - * @tfm - crypto driver; - */ -typedef struct { - ttls_cipher_id_t cipher; - int (*stream_func)(void *ctx, size_t length, const unsigned char *input, - unsigned char *output); - - struct crypto_aead * (*ctx_alloc_func)(void); - - void (*ctx_free_func)(struct crypto_aead *ctx); - - struct crypto_aead *tfm; -} ttls_cipher_base_t; - -/** - * Cipher information. Allows calling cipher functions in a generic way. - * - * @type - Full cipher identifier, e.g. TTLS_CIPHER_AES_256_CBC; - * @mode - The cipher mode. For example, TTLS_MODE_CBC; - * @key_len - The cipher key length, in bytes. This is the default length - * for variable sized ciphers. Includes parity bits for ciphers - * like DES; - * @name - Name of the cipher; - * @iv_size - IV or nonce size, in Bytes. For ciphers that accept variable - * IV sizes, this is the recommended size; - * @flags - Flags to set. For example, if the cipher supports variable IV - * sizes or variable key sizes; - * @block_size - The block size, in Bytes; - * @base - Struct for base cipher information and functions; - */ -typedef struct { - ttls_cipher_type_t type; - ttls_cipher_mode_t mode; - unsigned int key_len; - const char *name; - unsigned int iv_size; - int flags; - unsigned int block_size; - const ttls_cipher_base_t *base; -} ttls_cipher_info_t; - -/** - * Generic cipher context. - * - * @cipher_info - Information about the associated cipher; - * @cipher_ctx - The cipher-specific context; - * @iv_size - IV size in Bytes, for ciphers with variable-length - * IVs; - * @iv - Current IV; - */ -typedef struct { - const ttls_cipher_info_t *cipher_info; - struct crypto_aead *cipher_ctx; - unsigned char iv_size; - unsigned char iv[TTLS_MAX_IV_LENGTH]; -} TlsCipherCtx; - -const ttls_cipher_info_t *ttls_cipher_info_from_type( - const ttls_cipher_type_t cipher_type); - -void ttls_cipher_free(TlsCipherCtx *ctx); -int ttls_cipher_setup(TlsCipherCtx *ctx, const ttls_cipher_info_t *ci, - unsigned int tag_size); - -#endif /* TTLS_CIPHER_H */ diff --git a/tls/ciphersuites.c b/tls/ciphersuites.c index 97b8f5a88..bec4ddbb6 100644 --- a/tls/ciphersuites.c +++ b/tls/ciphersuites.c @@ -4,7 +4,7 @@ * TLS ciphersuites. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. * SPDX-License-Identifier: GPL-2.0 * * This program is free software; you can redistribute it and/or modify @@ -24,58 +24,6 @@ #include "ciphersuites.h" #include "ttls.h" -/* - * Ordered from most preferred to least preferred in terms of security. - * - * Current rule: - * 1. By key exchange: Forward-secure non-PSK > other non-PSK - * 2. By key length and cipher: AES-256 > AES-128 - * 3. By cipher mode when relevant GCM > CCM > CCM_8 - * 4. By hash function used when relevant - * 5. By key exchange/auth again: EC > non-EC - * - * Note that there is no TLS_RSA_WITH_AES_128_CBC_SHA required by RFC 5246. - * Current TLS version is 1.3, so we support TLS 1.2 for legacy only clients. - * Next, CBC mode has security issues (so it was removed from TLS 1.3) and - * incurs significant pipeline stalls that hamper its efficiency and - * performance. Last, it requires additional code work flow. - */ -static const int ciphersuite_preference[] = { - /* All AES-256 ephemeral suites */ - TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - TTLS_TLS_DHE_RSA_WITH_AES_256_CCM, - TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - TTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, - - /* All AES-128 ephemeral suites */ - TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - TTLS_TLS_DHE_RSA_WITH_AES_128_CCM, - TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - TTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, - - /* All AES-256 suites */ - TTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_RSA_WITH_AES_256_CCM, - TTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - TTLS_TLS_RSA_WITH_AES_256_CCM_8, - - /* All AES-128 suites */ - TTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_RSA_WITH_AES_128_CCM, - TTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - TTLS_TLS_RSA_WITH_AES_128_CCM_8, - - 0 -}; - static const TlsCiphersuite ciphersuite_definitions[] = { { TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, @@ -279,7 +227,7 @@ ttls_get_ciphersuite_name(const int ciphersuite_id) const TlsCiphersuite *cur; if (!(cur = ttls_ciphersuite_from_id(ciphersuite_id))) - return("unknown"); + return "unknown"; return cur->name; } diff --git a/tls/ciphersuites.h b/tls/ciphersuites.h index c5c04cbfa..129b91ab4 100644 --- a/tls/ciphersuites.h +++ b/tls/ciphersuites.h @@ -4,7 +4,7 @@ * TLS Ciphersuites definitions. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. * SPDX-License-Identifier: GPL-2.0 * * This program is free software; you can redistribute it and/or modify @@ -25,8 +25,7 @@ #define TTLS_CIPHERSUITES_H #include "pk.h" -#include "cipher.h" -#include "md.h" +#include "crypto.h" /* * Supported ciphersuites (Official IANA names) diff --git a/tls/config.h b/tls/config.h index fbde61b1a..be49ad12f 100644 --- a/tls/config.h +++ b/tls/config.h @@ -35,32 +35,6 @@ #define ttls_calloc(n, s) kzalloc((n) * (s), GFP_ATOMIC) #define ttls_free(p) kfree(p) -/** - * \def TTLS_AES_ALT - * - * TTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto, an arithmetic or hash - * module (e.g. platform specific assembly optimized implementations). Keep - * in mind that the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the TTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment TTLS_AES_ALT, mbed TLS will no longer - * provide the "struct ttls_aes_context" definition and omit the base - * function declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - * - * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their - * use constitutes a security risk. If possible, we recommend - * avoiding dependencies on them, and considering stronger message - * digests and ciphers instead. - * - */ -//#define TTLS_RSA_ALT /* * When replacing the elliptic curve module, pleace consider, that it is * implemented with two .c files: diff --git a/tls/crypto.c b/tls/crypto.c new file mode 100644 index 000000000..6c91d9e20 --- /dev/null +++ b/tls/crypto.c @@ -0,0 +1,470 @@ +/* + * Tempesta TLS + * + * Generic wrappers for Linux crypto API. + * + * Copyright (C) 2019 Tempesta Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include "lib/str.h" +#include "debug.h" +#include "crypto.h" + +/* + * ------------------------------------------------------------------------ + * Ciphers + * ------------------------------------------------------------------------ + */ +typedef struct { + ttls_cipher_type_t type; + TlsCipherInfo *info; +} TlsCipherDef; + +void +ttls_cipher_free(TlsCipherCtx *ctx) +{ + if (!ctx) + return; + if (ctx->cipher_ctx) + crypto_free_aead(ctx->cipher_ctx); + bzero_fast(ctx, sizeof(TlsCipherCtx)); +} + +int +ttls_cipher_setup(TlsCipherCtx *ctx, const TlsCipherInfo *ci, + unsigned int tag_size) +{ + int r; + + BUG_ON(!ci || !ctx); + + bzero_fast(ctx, sizeof(TlsCipherCtx)); + + ctx->cipher_ctx = crypto_alloc_aead_atomic(ci->alg); + if (IS_ERR(ctx->cipher_ctx)) + return PTR_ERR(ctx->cipher_ctx); + + if ((r = crypto_aead_setauthsize(ctx->cipher_ctx, tag_size))) { + ttls_cipher_free(ctx); + return r; + } + + /* See IV definitions for all cipher suites at the below. */ + WARN_ON_ONCE(crypto_aead_ivsize(ctx->cipher_ctx) != 12); + + ctx->cipher_info = ci; + + return 0; +} + +static TlsCipherInfo aes_128_gcm_info = { + TTLS_CIPHER_AES_128_GCM, + TTLS_MODE_GCM, + 16, + "AES-128-GCM", + "gcm(aes)", + 12, +}; + +static TlsCipherInfo aes_192_gcm_info = { + TTLS_CIPHER_AES_192_GCM, + TTLS_MODE_GCM, + 24, + "AES-192-GCM", + "gcm(aes)", + 12, +}; + +static TlsCipherInfo aes_256_gcm_info = { + TTLS_CIPHER_AES_256_GCM, + TTLS_MODE_GCM, + 32, + "AES-256-GCM", + "gcm(aes)", + 12, +}; + +static TlsCipherInfo aes_128_ccm_info = { + TTLS_CIPHER_AES_128_CCM, + TTLS_MODE_CCM, + 16, + "AES-128-CCM", + "ccm(aes)", + 12, +}; + +static TlsCipherInfo aes_192_ccm_info = { + TTLS_CIPHER_AES_192_CCM, + TTLS_MODE_CCM, + 24, + "AES-192-CCM", + "ccm(aes)", + 12, +}; + +static TlsCipherInfo aes_256_ccm_info = { + TTLS_CIPHER_AES_256_CCM, + TTLS_MODE_CCM, + 32, + "AES-256-CCM", + "ccm(aes)", + 12, +}; + +static TlsCipherDef ttls_ciphers[] = { + { TTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { TTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { TTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, + { TTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { TTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { TTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, + { TTLS_CIPHER_NONE, NULL } +}; + +const TlsCipherInfo * +ttls_cipher_info_from_type(const ttls_cipher_type_t cipher_type) +{ + const TlsCipherDef *def; + + for (def = ttls_ciphers; def->info; def++) + if (def->type == cipher_type) + return def->info; + return NULL; +} + +/* + * ------------------------------------------------------------------------ + * Message digests + * ------------------------------------------------------------------------ + */ +typedef struct { + ttls_md_type_t type; + TlsMdInfo *info; +} TlsHashDef; + +static TlsMdInfo ttls_sha224_info = { + .type = TTLS_MD_SHA224, + .name = "SHA224", + .alg_name = "sha224-avx2", + .hmac_name = "hmac(sha224-avx2)", +}; + +static TlsMdInfo ttls_sha256_info = { + .type = TTLS_MD_SHA256, + .name = "SHA256", + .alg_name = "sha256-avx2", + .hmac_name = "hmac(sha256-avx2)", +}; + +static TlsMdInfo ttls_sha384_info = { + .type = TTLS_MD_SHA384, + .name = "SHA384", + .alg_name = "sha384-avx2", + .hmac_name = "hmac(sha384-avx2)", +}; + +static TlsMdInfo ttls_sha512_info = { + .type = TTLS_MD_SHA512, + .name = "SHA512", + .alg_name = "sha512-avx2", + .hmac_name = "hmac(sha512-avx2)", +}; + +/* + * Reminder: update profiles in x509_crt.c when adding a new hash! + */ +static TlsHashDef ttls_hashes[] = { + { TTLS_MD_SHA512, &ttls_sha512_info }, + { TTLS_MD_SHA384, &ttls_sha384_info }, + { TTLS_MD_SHA256, &ttls_sha256_info }, + { TTLS_MD_SHA224, &ttls_sha224_info }, + { TTLS_MD_NONE, NULL } +}; + +void +ttls_md_init(TlsMdCtx *ctx) +{ + bzero_fast(ctx, sizeof(TlsMdCtx)); +} + +void +ttls_md_free(TlsMdCtx *ctx) +{ + if (!ctx) + return; + crypto_free_shash(ctx->md_ctx.tfm); + bzero_fast(ctx, sizeof(TlsMdCtx)); +} + +static int +__ttls_md_hash_setup(struct shash_desc *md_ctx, const TlsMdInfo *md_info) +{ + md_ctx->tfm = crypto_alloc_shash_atomic(md_info->alg_hash); + if (IS_ERR(md_ctx->tfm)) { + T_DBG("Cannot setup hash ctx, %ld\n", PTR_ERR(md_ctx->tfm)); + return PTR_ERR(md_ctx->tfm); + } + + return 0; +} + +static int +__ttls_md_hmac_setup(struct shash_desc *md_ctx, const TlsMdInfo *md_info) +{ + md_ctx->tfm = crypto_alloc_shash_atomic(md_info->alg_hmac); + if (IS_ERR(md_ctx->tfm)) { + T_DBG("Cannot setup hmac ctx, %ld\n", PTR_ERR(md_ctx->tfm)); + return PTR_ERR(md_ctx->tfm); + } + + return 0; +} + +int +ttls_md_setup(TlsMdCtx *ctx, const TlsMdInfo *md_info, int hmac) +{ + BUG_ON(!ctx); + if (WARN_ON_ONCE(!md_info)) + return -EINVAL; + + ctx->md_info = md_info; + + return hmac ? __ttls_md_hmac_setup(&ctx->md_ctx, md_info) + : __ttls_md_hash_setup(&ctx->md_ctx, md_info); +} + +int +ttls_md_starts(TlsMdCtx *ctx) +{ + int r; + + BUG_ON(!ctx || !ctx->md_info); + + r = crypto_shash_init(&ctx->md_ctx); + if (r) + T_DBG("cannot start hash ctx, %d\n", r); + + return r; +} + +int +ttls_md_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen) +{ + int r; + + BUG_ON(!ctx || !ctx->md_info); + + r = crypto_shash_update(&ctx->md_ctx, input, ilen); + if (r) + T_DBG("cannot update hash ctx, %d\n", r); + + return r; +} + +int +ttls_md_finish(TlsMdCtx *ctx, unsigned char *output) +{ + int r; + + BUG_ON(!ctx || !ctx->md_info); + + r = crypto_shash_final(&ctx->md_ctx, output); + if (r) + T_DBG("cannot finish hash context, %d\n", r); + + return r; +} + +int +ttls_md(const TlsMdInfo *md_info, const unsigned char *input, size_t ilen, + unsigned char *output) +{ + int r; + TlsMdCtx ctx; + + BUG_ON(!md_info); + + ttls_md_init(&ctx); + if ((r = ttls_md_setup(&ctx, md_info, 0))) + return r; + r = crypto_shash_digest(&ctx.md_ctx, input, ilen, output); + ttls_md_free(&ctx); + + return r; +} + +int +ttls_sha256_init_start(ttls_sha256_context *ctx) +{ + int r; + + if ((r = __ttls_md_hash_setup(&ctx->desc, &ttls_sha256_info))) + return r; + ctx->desc.flags = 0; + + return crypto_shash_init(&ctx->desc); +} + +int +ttls_sha384_init_start(ttls_sha512_context *ctx) +{ + int r; + + if ((r = __ttls_md_hash_setup(&ctx->desc, &ttls_sha384_info))) + return r; + ctx->desc.flags = 0; + + return crypto_shash_init(&ctx->desc); +} + +int +ttls_md_hmac_starts(TlsMdCtx *ctx, const unsigned char *key, size_t keylen) +{ + int r; + + if ((r = crypto_shash_setkey(ctx->md_ctx.tfm, key, keylen))) + return r; + return crypto_shash_init(&ctx->md_ctx); +} + +int +ttls_md_hmac_reset(TlsMdCtx *ctx) +{ + BUG_ON(!ctx || !ctx->md_info); + + return crypto_shash_init(&ctx->md_ctx); +} + +const TlsMdInfo * +ttls_md_info_from_type(ttls_md_type_t md_type) +{ + switch (md_type) { + case TTLS_MD_SHA224: + return &ttls_sha224_info; + case TTLS_MD_SHA256: + return &ttls_sha256_info; + case TTLS_MD_SHA384: + return &ttls_sha384_info; + case TTLS_MD_SHA512: + return &ttls_sha512_info; + default: + return NULL; + } +} + +/* + * ------------------------------------------------------------------------ + * Common initialization routines + * ------------------------------------------------------------------------ + */ +static unsigned int g_aead_max_reqsize = sizeof(struct aead_request); + +unsigned int +ttls_aead_reqsize(void) +{ + return g_aead_max_reqsize; +} + +/** + * Crypto framework may load crypto modules on the fly during a particular + * algorithm initialization, so the two routines at the below just allocate and + * immediately free algorithm descriptors to make all the necessary modules + * loaded. + */ +static int __init +ttls_ciphermod_preload(const char *alg_name) +{ + unsigned int rs; + struct crypto_aead *a = crypto_alloc_aead(alg_name, 0, 0); + + if (IS_ERR(a)) { + T_ERR("Cannot preload %s module, please check /proc/crypto.\n", + alg_name); + return PTR_ERR(a); + } + + rs = crypto_aead_reqsize(a) + sizeof(struct aead_request); + if (rs > g_aead_max_reqsize) + g_aead_max_reqsize = rs; + + crypto_free_aead(a); + + return 0; +} + +static int __init +ttls_hashmod_preload(const char *alg_name) +{ + struct crypto_shash *h = crypto_alloc_shash(alg_name, 0, 0); + + if (IS_ERR(h)) { + T_ERR("Cannot preload %s module, please check /proc/crypto.\n", + alg_name); + return PTR_ERR(h); + } + crypto_free_shash(h); + + return 0; +} + +int __init +ttls_crypto_modinit(void) +{ + int r; + const char *name; + TlsCipherDef *c; + TlsHashDef *h; + + for (c = ttls_ciphers; c->info; c++) { + name = c->info->drv_name; + if ((r = ttls_ciphermod_preload(name))) + return r; + c->info->alg = crypto_find_aead(name, 0, 0); + if (IS_ERR(c->info->alg)) { + r = PTR_ERR(c->info->alg); + goto err; + } + } + + for (h = ttls_hashes; h->info; h++) { + name = h->info->alg_name; + if ((r = ttls_hashmod_preload(name))) + return r; + h->info->alg_hash = crypto_find_shash(name, 0, 0); + if (IS_ERR(h->info->alg_hash)) { + r = PTR_ERR(h->info->alg_hash); + goto err; + } + + name = h->info->hmac_name; + if ((r = ttls_hashmod_preload(name))) + return r; + h->info->alg_hmac = crypto_find_shash(name, 0, 0); + if (IS_ERR(h->info->alg_hmac)) { + r = PTR_ERR(h->info->alg_hmac); + goto err; + } + } + + return 0; +err: + T_ERR("Cannot find %s algorithm, please check /proc/crypto for it\n", + name); + return r; +} diff --git a/tls/crypto.h b/tls/crypto.h new file mode 100644 index 000000000..d9da4c1a4 --- /dev/null +++ b/tls/crypto.h @@ -0,0 +1,225 @@ +/* + * Tempesta TLS + * + * Copyright (C) 2019 Tempesta Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __TTLS_CRYPTO_H__ +#define __TTLS_CRYPTO_H__ + +#include +#include + +/* An enumeration of supported ciphers. */ +typedef enum { + TTLS_CIPHER_ID_NONE = 0, + TTLS_CIPHER_ID_AES, +} ttls_cipher_id_t; + +/* Supported (cipher, mode) pairs. */ +typedef enum { + TTLS_CIPHER_NONE = 0, + TTLS_CIPHER_AES_128_GCM, + TTLS_CIPHER_AES_192_GCM, + TTLS_CIPHER_AES_256_GCM, + TTLS_CIPHER_AES_128_CCM, + TTLS_CIPHER_AES_192_CCM, + TTLS_CIPHER_AES_256_CCM, +} ttls_cipher_type_t; + +/* Supported cipher modes. */ +typedef enum { + TTLS_MODE_NONE = 0, + TTLS_MODE_GCM, + TTLS_MODE_STREAM, /* TLS 1.3: ChaCha20-Poly1305 */ + TTLS_MODE_CCM, +} ttls_cipher_mode_t; + +/* Supported cipher padding types. */ +typedef enum { + TTLS_PADDING_PKCS7 = 0, /* PKCS7 padding (default) */ + TTLS_PADDING_ONE_AND_ZEROS, /* ISO/IEC 7816-4 padding */ + TTLS_PADDING_ZEROS_AND_LEN, /* ANSI X.923 padding */ + TTLS_PADDING_ZEROS, /* zero padding (not reversible) */ + TTLS_PADDING_NONE, /* never pad (full blocks only) */ +} ttls_cipher_padding_t; + +/* Supported message digests. */ +typedef enum { + TTLS_MD_NONE = 0, + TTLS_MD_SHA1, + TTLS_MD_SHA224, + TTLS_MD_SHA256, + TTLS_MD_SHA384, + TTLS_MD_SHA512, +} ttls_md_type_t; + +/** Maximum length of any IV, in Bytes. */ +#define TTLS_MAX_IV_LENGTH 16 +#define TTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ +#define __MD_MAX_CTX_SZ sizeof(struct sha512_state) + +/** + * Cipher information. Allows calling cipher functions in a generic way. + * + * @type - Full cipher identifier, e.g. TTLS_CIPHER_AES_256_CBC; + * @mode - The cipher mode. For example, TTLS_MODE_CBC; + * @key_len - The cipher key length, in bytes. This is the default length + * for variable sized ciphers. Includes parity bits for ciphers + * like DES; + * @name - Name of the cipher; + * @drv_name - Name of appropriate Linux crypto driver; + * @iv_size - IV or nonce size, in Bytes. For ciphers that accept variable + * IV sizes, this is the recommended size; + * @alg - Crypto algorithm descriptor; + */ +typedef struct { + ttls_cipher_type_t type; + ttls_cipher_mode_t mode; + unsigned int key_len; + const char *name; + const char *drv_name; + unsigned int iv_size; + struct crypto_alg *alg; +} TlsCipherInfo; + +/** + * Generic cipher context. + * + * @cipher_info - Information about the associated cipher; + * @cipher_ctx - The cipher-specific context; + * @iv_size - IV size in Bytes, for ciphers with variable-length + * IVs; + * @iv - Current IV; + */ +typedef struct { + const TlsCipherInfo *cipher_info; + struct crypto_aead *cipher_ctx; + unsigned char iv_size; + unsigned char iv[TTLS_MAX_IV_LENGTH]; +} TlsCipherCtx; + +/** + * Message digest information. + * Allows message digest functions to be called in a generic way. + * + * @type - Digest identifier; + * @name - Name of the message digest; + * @alg_name - hash Linux crypto driver; + * @hmac_name - HMAC Linux crypto driver; + * @alg_hash - Hash algorithm descriptor; + * @alg_hmac - HMAC algorithm descriptor; + */ +typedef struct TlsMdInfo { + ttls_md_type_t type; + const char *name; + const char *alg_name; + const char *hmac_name; + struct crypto_alg *alg_hash; + struct crypto_alg *alg_hmac; +} TlsMdInfo; + +/** + * The generic message-digest context. + * + * @md_info - Information about the associated message digest; + * @md_ctx - The digest-specific context; + */ +typedef struct { + const TlsMdInfo *md_info; + struct shash_desc md_ctx; + char __ctx[__MD_MAX_CTX_SZ]; +} TlsMdCtx; + +typedef struct { + struct shash_desc desc; + struct sha256_state state; +} CRYPTO_MINALIGN_ATTR ttls_sha256_context; + +typedef struct { + struct shash_desc desc; + struct sha512_state state; +} CRYPTO_MINALIGN_ATTR ttls_sha512_context; + +const TlsCipherInfo * +ttls_cipher_info_from_type(const ttls_cipher_type_t cipher_type); + +void ttls_cipher_free(TlsCipherCtx *ctx); +int ttls_cipher_setup(TlsCipherCtx *ctx, const TlsCipherInfo *ci, + unsigned int tag_size); + +const TlsMdInfo *ttls_md_info_from_type(ttls_md_type_t md_type); +void ttls_md_init(TlsMdCtx *ctx); +void ttls_md_free(TlsMdCtx *ctx); + +/* + * This function selects the message digest algorithm to use, and allocates + * internal structures. It should be called after ttls_md_init() or + * ttls_md_free(). Makes it necessary to call ttls_md_free() later. + */ +int ttls_md_setup(TlsMdCtx *ctx, const TlsMdInfo *md_info, int hmac); + +int ttls_md_starts(TlsMdCtx *ctx); +int ttls_md_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen); +int ttls_md_finish(TlsMdCtx *ctx, unsigned char *output); + +/* + * This function calculates the message-digest of a buffer, with respect to a + * configurable message-digest algorithm in a single call. + */ +int ttls_md(const TlsMdInfo *md_info, const unsigned char *input, + size_t ilen, unsigned char *output); + +int ttls_sha256_init_start(ttls_sha256_context *ctx); +int ttls_sha384_init_start(ttls_sha512_context *ctx); + +int ttls_md_hmac_starts(TlsMdCtx *ctx, const unsigned char *key, size_t keylen); +int ttls_md_hmac_reset(TlsMdCtx *ctx); + +unsigned int ttls_aead_reqsize(void); +int ttls_crypto_modinit(void); + +static inline int +ttls_md_hmac_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen) +{ + return ttls_md_update(ctx, input, ilen); +} + +static inline int +ttls_md_hmac_finish(TlsMdCtx *ctx, unsigned char *output) +{ + return ttls_md_finish(ctx, output); +} + +static inline unsigned char +ttls_md_get_size(const TlsMdInfo *md_info) +{ + struct crypto_alg *alg = md_info->alg_hash ? : md_info->alg_hmac; + + BUG_ON(!md_info || !alg); + + return __crypto_shash_alg(alg)->digestsize; +} + +static inline const char * +ttls_md_get_name(const TlsMdInfo *md_info) +{ + BUG_ON(!md_info); + + return md_info->name; +} + +#endif /* __TTLS_CRYPTO_H__ */ diff --git a/tls/ecdsa.h b/tls/ecdsa.h index b2a8b62aa..c9d452737 100644 --- a/tls/ecdsa.h +++ b/tls/ecdsa.h @@ -9,6 +9,7 @@ * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). * * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. * SPDX-License-Identifier: GPL-2.0 * * This program is free software; you can redistribute it and/or modify @@ -29,7 +30,7 @@ #define TTLS_ECDSA_H #include "ecp.h" -#include "md.h" +#include "crypto.h" /* * RFC-4492 page 20: @@ -56,10 +57,6 @@ */ typedef ttls_ecp_keypair ttls_ecdsa_context; -#ifdef __cplusplus -extern "C" { -#endif - /** * \brief This function computes the ECDSA signature of a * previously-hashed message. @@ -188,8 +185,4 @@ void ttls_ecdsa_init(ttls_ecdsa_context *ctx); */ void ttls_ecdsa_free(ttls_ecdsa_context *ctx); -#ifdef __cplusplus -} -#endif - #endif /* ecdsa.h */ diff --git a/tls/error.c b/tls/error.c index 1fa69f580..07a7b7085 100644 --- a/tls/error.c +++ b/tls/error.c @@ -1,34 +1,33 @@ -/* - * Error message information +/** + * Tempesta TLS * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 + * Error message information. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. + * SPDX-License-Identifier: GPL-2.0 * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This file is part of mbed TLS (https://tls.mbed.org) + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "bignum.h" -#include "cipher.h" +#include "crypto.h" #if defined(TTLS_DHM_C) #include "dhm.h" #endif #include "ecp.h" -#include "md.h" #include "oid.h" #include "pem.h" #include "pk.h" @@ -57,26 +56,6 @@ void ttls_strerror(int ret, char *buf, size_t buflen) { use_ret = ret & 0xFF80; - // High level error codes - // - // BEGIN generated code - if (use_ret == -(TTLS_ERR_CIPHER_FEATURE_UNAVAILABLE)) - snprintf(buf, buflen, "CIPHER - The selected feature is not available"); - if (use_ret == -(TTLS_ERR_CIPHER_BAD_INPUT_DATA)) - snprintf(buf, buflen, "CIPHER - Bad input parameters"); - if (use_ret == -(TTLS_ERR_CIPHER_ALLOC_FAILED)) - snprintf(buf, buflen, "CIPHER - Failed to allocate memory"); - if (use_ret == -(TTLS_ERR_CIPHER_INVALID_PADDING)) - snprintf(buf, buflen, "CIPHER - Input data contains invalid padding and is rejected"); - if (use_ret == -(TTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED)) - snprintf(buf, buflen, "CIPHER - Decryption of block requires a full block"); - if (use_ret == -(TTLS_ERR_CIPHER_AUTH_FAILED)) - snprintf(buf, buflen, "CIPHER - Authentication failed (for AEAD modes)"); - if (use_ret == -(TTLS_ERR_CIPHER_INVALID_CONTEXT)) - snprintf(buf, buflen, "CIPHER - The context is invalid. For example, because it was freed"); - if (use_ret == -(TTLS_ERR_CIPHER_HW_ACCEL_FAILED)) - snprintf(buf, buflen, "CIPHER - Cipher hardware accelerator failed"); - #if defined(TTLS_DHM_C) if (use_ret == -(TTLS_ERR_DHM_BAD_INPUT_DATA)) snprintf(buf, buflen, "DHM - Bad input parameters"); @@ -121,17 +100,6 @@ void ttls_strerror(int ret, char *buf, size_t buflen) if (use_ret == -(TTLS_ERR_ECP_HW_ACCEL_FAILED)) snprintf(buf, buflen, "ECP - ECP hardware accelerator failed"); - if (use_ret == -(TTLS_ERR_MD_FEATURE_UNAVAILABLE)) - snprintf(buf, buflen, "MD - The selected feature is not available"); - if (use_ret == -(TTLS_ERR_MD_BAD_INPUT_DATA)) - snprintf(buf, buflen, "MD - Bad input parameters to function"); - if (use_ret == -(TTLS_ERR_MD_ALLOC_FAILED)) - snprintf(buf, buflen, "MD - Failed to allocate memory"); - if (use_ret == -(TTLS_ERR_MD_FILE_IO_ERROR)) - snprintf(buf, buflen, "MD - Opening or reading of file failed"); - if (use_ret == -(TTLS_ERR_MD_HW_ACCEL_FAILED)) - snprintf(buf, buflen, "MD - MD hardware accelerator failed"); - if (use_ret == -(TTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT)) snprintf(buf, buflen, "PEM - No PEM header or footer found"); if (use_ret == -(TTLS_ERR_PEM_INVALID_DATA)) @@ -213,8 +181,6 @@ void ttls_strerror(int ret, char *buf, size_t buflen) snprintf(buf, buflen, "TLS - An invalid TLS record was received"); if (use_ret == -(TTLS_ERR_CONN_EOF)) snprintf(buf, buflen, "TLS - The connection indicated an EOF"); - if (use_ret == -(TTLS_ERR_NO_CIPHER_CHOSEN)) - snprintf(buf, buflen, "TLS - The server has no ciphersuites in common with the client"); if (use_ret == -(TTLS_ERR_NO_CLIENT_CERTIFICATE)) snprintf(buf, buflen, "TLS - No client certification received from the client, but required by the authentication mode"); if (use_ret == -(TTLS_ERR_CERTIFICATE_TOO_LARGE)) @@ -265,8 +231,6 @@ void ttls_strerror(int ret, char *buf, size_t buflen) snprintf(buf, buflen, "TLS - Internal error (eg, unexpected failure in lower-level module)"); if (use_ret == -(TTLS_ERR_BUFFER_TOO_SMALL)) snprintf(buf, buflen, "TLS - A buffer is too small to receive or write a message"); - if (use_ret == -(TTLS_ERR_NO_USABLE_CIPHERSUITE)) - snprintf(buf, buflen, "TLS - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)"); if (use_ret == -(TTLS_ERR_INVALID_VERIFY_HASH)) snprintf(buf, buflen, "TLS - Couldn't set the hash for verifying CertificateVerify"); diff --git a/tls/md.c b/tls/md.c deleted file mode 100644 index 0d637092f..000000000 --- a/tls/md.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Tempesta TLS - * - * Generic message digest wrapper. - * - * Adriaan de Jong - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include "lib/str.h" -#include "debug.h" -#include "md.h" - -/* - * Reminder: update profiles in x509_crt.c when adding a new hash! - */ -static const int supported_digests[] = { - TTLS_MD_SHA512, - TTLS_MD_SHA384, - TTLS_MD_SHA256, - TTLS_MD_SHA224, - TTLS_MD_NONE -}; - -TlsMdInfo ttls_sha224_info = { - .type = TTLS_MD_SHA224, - .name = "SHA224", - .alg_name = "sha224-avx2", - .hmac_name = "hmac(sha224-avx2)", - .size = 28, - .block_size = 64, -}; - -TlsMdInfo ttls_sha256_info = { - .type = TTLS_MD_SHA256, - .name = "SHA256", - .alg_name = "sha256-avx2", - .hmac_name = "hmac(sha256-avx2)", - .size = 32, - .block_size = 64, -}; - -TlsMdInfo ttls_sha384_info = { - .type = TTLS_MD_SHA384, - .name = "SHA384", - .alg_name = "sha384-avx2", - .hmac_name = "hmac(sha384-avx2)", - .size = 48, - .block_size = 128, -}; - -TlsMdInfo ttls_sha512_info = { - .type = TTLS_MD_SHA512, - .name = "SHA512", - .alg_name = "sha512-avx2", - .hmac_name = "hmac(sha512-avx2)", - .size = 64, - .block_size = 128, -}; - -void -ttls_md_init(TlsMdCtx *ctx) -{ - bzero_fast(ctx, sizeof(TlsMdCtx)); -} - -void -ttls_md_free(TlsMdCtx *ctx) -{ - if (ctx) - crypto_free_shash(ctx->md_ctx.tfm); -} - -static int -__ttls_md_hash_setup(struct shash_desc *md_ctx, const TlsMdInfo *md_info) -{ - md_ctx->tfm = crypto_alloc_shash(md_info->alg_name, 0, 0); - if (IS_ERR(md_ctx->tfm)) { - T_ERR("cannot initialize hash driver %s." - " Please check /proc/crypto for the algorithm\n", - md_info->alg_name); - return TTLS_ERR_MD_ALLOC_FAILED; - } - - return 0; -} - -static int -__ttls_md_hmac_setup(struct shash_desc *md_ctx, const TlsMdInfo *md_info) -{ - md_ctx->tfm = crypto_alloc_shash(md_info->hmac_name, 0, 0); - if (IS_ERR(md_ctx->tfm)) { - T_ERR("cannot initialize HMAC driver %s." - " Please check /proc/crypto for the algorithm\n", - md_info->hmac_name); - return TTLS_ERR_MD_ALLOC_FAILED; - } - - return 0; -} - -int -ttls_md_setup(TlsMdCtx *ctx, const TlsMdInfo *md_info, int hmac) -{ - BUG_ON(!ctx); - if (WARN_ON_ONCE(!md_info)) - return -EINVAL; - - ctx->md_info = md_info; - - return hmac ? __ttls_md_hmac_setup(&ctx->md_ctx, md_info) - : __ttls_md_hash_setup(&ctx->md_ctx, md_info); -} - -int -ttls_md_starts(TlsMdCtx *ctx) -{ - BUG_ON(!ctx || !ctx->md_info); - - return crypto_shash_init(&ctx->md_ctx); -} - -int -ttls_md_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen) -{ - BUG_ON(!ctx || !ctx->md_info); - - return crypto_shash_update(&ctx->md_ctx, input, ilen); -} - -int -ttls_md_finish(TlsMdCtx *ctx, unsigned char *output) -{ - BUG_ON(!ctx || !ctx->md_info); - - return crypto_shash_final(&ctx->md_ctx, output); -} - -int -ttls_md(const TlsMdInfo *md_info, const unsigned char *input, size_t ilen, - unsigned char *output) -{ - int r; - TlsMdCtx ctx; - - BUG_ON(!md_info); - - ttls_md_init(&ctx); - if ((r = ttls_md_setup(&ctx, md_info, 0))) - return r; - r = crypto_shash_digest(&ctx.md_ctx, input, ilen, output); - ttls_md_free(&ctx); - - return r; -} - -int -ttls_sha256_init_start(ttls_sha256_context *ctx) -{ - int r; - - if ((r = __ttls_md_hash_setup(&ctx->desc, &ttls_sha256_info))) - return r; - ctx->desc.flags = 0; - - return crypto_shash_init(&ctx->desc); -} - -int -ttls_sha384_init_start(ttls_sha512_context *ctx) -{ - int r; - - if ((r = __ttls_md_hash_setup(&ctx->desc, &ttls_sha384_info))) - return r; - ctx->desc.flags = 0; - - return crypto_shash_init(&ctx->desc); -} - -int -ttls_md_hmac_starts(TlsMdCtx *ctx, const unsigned char *key, size_t keylen) -{ - int r; - - if ((r = crypto_shash_setkey(ctx->md_ctx.tfm, key, keylen))) - return r; - return crypto_shash_init(&ctx->md_ctx); -} - -int -ttls_md_hmac_reset(TlsMdCtx *ctx) -{ - BUG_ON(!ctx || !ctx->md_info); - - return crypto_shash_init(&ctx->md_ctx); -} - -const TlsMdInfo * -ttls_md_info_from_type(ttls_md_type_t md_type) -{ - switch(md_type) { - case TTLS_MD_SHA224: - return &ttls_sha224_info; - case TTLS_MD_SHA256: - return &ttls_sha256_info; - case TTLS_MD_SHA384: - return &ttls_sha384_info; - case TTLS_MD_SHA512: - return &ttls_sha512_info; - default: - return NULL; - } -} diff --git a/tls/md.h b/tls/md.h deleted file mode 100644 index bb8827f34..000000000 --- a/tls/md.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Tempesta TLS - * - * Adriaan de Jong - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef TTLS_MD_H -#define TTLS_MD_H - -#include -#include - -/**< The selected feature is not available. */ -#define TTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 -/**< Bad input parameters to function. */ -#define TTLS_ERR_MD_BAD_INPUT_DATA -0x5100 -/**< Failed to allocate memory. */ -#define TTLS_ERR_MD_ALLOC_FAILED -0x5180 -/**< Opening or reading of file failed. */ -#define TTLS_ERR_MD_FILE_IO_ERROR -0x5200 -/**< MD hardware accelerator failed. */ -#define TTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 - -/* Supported message digests. */ -typedef enum { - TTLS_MD_NONE = 0, - TTLS_MD_SHA1, - TTLS_MD_SHA224, - TTLS_MD_SHA256, - TTLS_MD_SHA384, - TTLS_MD_SHA512, -} ttls_md_type_t; - -#define TTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ -#define __MD_MAX_CTX_SZ sizeof(struct sha512_state) - -/** - * Message digest information. - * Allows message digest functions to be called in a generic way. - * - * @type - Digest identifier; - * @name - Name of the message digest; - * @alg_name - hash Linux crypto driver; - * @hmac_name - HMAC Linux crypto driver; - * @size - Output length of the digest function in bytes; - * @block_size - Block length of the digest function in bytes; - */ -typedef struct TlsMdInfo { - ttls_md_type_t type; - const char *name; - const char *alg_name; - const char *hmac_name; - int size; - int block_size; -} TlsMdInfo; - -/** - * The generic message-digest context. - * - * @md_info - Information about the associated message digest; - * @md_ctx - The digest-specific context; - */ -typedef struct { - const TlsMdInfo *md_info; - struct shash_desc md_ctx; - char __ctx[__MD_MAX_CTX_SZ]; -} TlsMdCtx; - -typedef struct { - struct shash_desc desc; - struct sha256_state state; -} CRYPTO_MINALIGN_ATTR ttls_sha256_context; - -typedef struct { - struct shash_desc desc; - struct sha512_state state; -} CRYPTO_MINALIGN_ATTR ttls_sha512_context; - -const TlsMdInfo *ttls_md_info_from_type(ttls_md_type_t md_type); -void ttls_md_init(TlsMdCtx *ctx); -void ttls_md_free(TlsMdCtx *ctx); - -/* - * This function selects the message digest algorithm to use, and allocates - * internal structures. It should be called after ttls_md_init() or - * ttls_md_free(). Makes it necessary to call ttls_md_free() later. - */ -int ttls_md_setup(TlsMdCtx *ctx, const TlsMdInfo *md_info, int hmac); - -int ttls_md_starts(TlsMdCtx *ctx); -int ttls_md_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen); -int ttls_md_finish(TlsMdCtx *ctx, unsigned char *output); - -/* - * This function calculates the message-digest of a buffer, with respect to a - * configurable message-digest algorithm in a single call. - */ -int ttls_md(const TlsMdInfo *md_info, const unsigned char *input, - size_t ilen, unsigned char *output); - -int ttls_sha256_init_start(ttls_sha256_context *ctx); -int ttls_sha384_init_start(ttls_sha512_context *ctx); - -int ttls_md_hmac_starts(TlsMdCtx *ctx, const unsigned char *key, size_t keylen); -int ttls_md_hmac_reset(TlsMdCtx *ctx); - -static inline int -ttls_md_hmac_update(TlsMdCtx *ctx, const unsigned char *input, size_t ilen) -{ - return ttls_md_update(ctx, input, ilen); -} - -static inline int -ttls_md_hmac_finish(TlsMdCtx *ctx, unsigned char *output) -{ - return ttls_md_finish(ctx, output); -} - -static inline unsigned char -ttls_md_get_size(const TlsMdInfo *md_info) -{ - BUG_ON(!md_info); - - return md_info->size; -} - -static inline const char * -ttls_md_get_name(const TlsMdInfo *md_info) -{ - BUG_ON(!md_info); - - return md_info->name; -} - -#endif /* TTLS_MD_H */ diff --git a/tls/oid.h b/tls/oid.h index 2618a2998..29db9e4a7 100644 --- a/tls/oid.h +++ b/tls/oid.h @@ -1,36 +1,32 @@ /** - * \file oid.h + * Tempesta TLS * - * \brief Object Identifier (OID) database - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 + * Object Identifier (OID) database. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. + * SPDX-License-Identifier: GPL-2.0 * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This file is part of mbed TLS (https://tls.mbed.org) + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TTLS_OID_H #define TTLS_OID_H #include "config.h" #include "asn1.h" #include "pk.h" -#include "cipher.h" -#include "md.h" +#include "crypto.h" #include "x509.h" #define TTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */ diff --git a/tls/pem.c b/tls/pem.c index cbc4c526d..a12266193 100644 --- a/tls/pem.c +++ b/tls/pem.c @@ -21,8 +21,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "crypto.h" #include "pem.h" -#include "cipher.h" #include "tls_internal.h" static const unsigned char base64_dec_map[128] = { diff --git a/tls/pk.h b/tls/pk.h index d0636044f..4a3a09064 100644 --- a/tls/pk.h +++ b/tls/pk.h @@ -24,7 +24,7 @@ #ifndef TTLS_PK_H #define TTLS_PK_H -#include "md.h" +#include "crypto.h" #include "rsa.h" #include "ecp.h" #include "ecdsa.h" diff --git a/tls/pk_wrap.c b/tls/pk_wrap.c index 191641511..ca53d063f 100644 --- a/tls/pk_wrap.c +++ b/tls/pk_wrap.c @@ -4,7 +4,7 @@ * Public Key abstraction layer: wrapper functions. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. * SPDX-License-Identifier: GPL-2.0 * * This program is free software; you can redistribute it and/or modify @@ -110,20 +110,22 @@ static int rsa_check_pair_wrap(const void *pub, const void *prv) (const ttls_rsa_context *) prv)); } -static void *rsa_alloc_wrap(void) +static void * +rsa_alloc_wrap(void) { - void *ctx = ttls_calloc(1, sizeof(ttls_rsa_context)); + void *ctx; - if (ctx != NULL) - ttls_rsa_init((ttls_rsa_context *) ctx, 0, 0); + might_sleep(); + if ((ctx = kzalloc(sizeof(ttls_rsa_context), GFP_KERNEL))) + ttls_rsa_init((ttls_rsa_context *)ctx, 0, 0); - return(ctx); + return ctx; } static void rsa_free_wrap(void *ctx) { ttls_rsa_free((ttls_rsa_context *) ctx); - ttls_free(ctx); + kfree(ctx); } static void rsa_debug(const void *ctx, ttls_pk_debug_item *items) @@ -218,20 +220,20 @@ static int eckey_check_pair(const void *pub, const void *prv) (const ttls_ecp_keypair *) prv)); } -static void *eckey_alloc_wrap(void) +static void * +eckey_alloc_wrap(void) { - void *ctx = ttls_calloc(1, sizeof(ttls_ecp_keypair)); - - if (ctx != NULL) + void *ctx = kzalloc(sizeof(ttls_ecp_keypair), GFP_ATOMIC); + if (!ctx) ttls_ecp_keypair_init(ctx); - return(ctx); + return ctx; } static void eckey_free_wrap(void *ctx) { ttls_ecp_keypair_free((ttls_ecp_keypair *) ctx); - ttls_free(ctx); + kfree(ctx); } static void eckey_debug(const void *ctx, ttls_pk_debug_item *items) diff --git a/tls/rsa.c b/tls/rsa.c index 859d08f36..6663309b0 100644 --- a/tls/rsa.c +++ b/tls/rsa.c @@ -1,55 +1,54 @@ -/* - * The RSA public-key cryptosystem +/** + * Tempesta TLS * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 + * The RSA public-key cryptosystem. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * TODO #1064: The Linux crypt API already has RSA implementation, so probably + * the stuff below should be just thrown out. Fallback to GPU is necessary + * however, so maybe not... A careful rethinking is requiered. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * The following sources were referenced in the design of this implementation + * of the RSA algorithm: * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * [1] A method for obtaining digital signatures and public-key cryptosystems + * R Rivest, A Shamir, and L Adleman + * http://people.csail.mit.edu/rivest/pubs.html#RSA78 * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The following sources were referenced in the design of this implementation - * of the RSA algorithm: + * [2] Handbook of Applied Cryptography - 1997, Chapter 8 + * Menezes, van Oorschot and Vanstone + * + * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks + * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and + * Stefan Mangard + * https://arxiv.org/abs/1702.08719v2 * - * [1] A method for obtaining digital signatures and public-key cryptosystems - * R Rivest, A Shamir, and L Adleman - * http://people.csail.mit.edu/rivest/pubs.html#RSA78 + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. + * SPDX-License-Identifier: GPL-2.0 * - * [2] Handbook of Applied Cryptography - 1997, Chapter 8 - * Menezes, van Oorschot and Vanstone + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks - * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and - * Stefan Mangard - * https://arxiv.org/abs/1702.08719v2 + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "lib/str.h" #include "config.h" +#include "crypto.h" #include "rsa.h" #include "rsa_internal.h" #include "tls_internal.h" #include "oid.h" -#include "md.h" - -#if !defined(TTLS_RSA_ALT) /* constant-time buffer comparison */ static inline int ttls_safer_memcmp(const void *a, const void *b, size_t n) @@ -430,36 +429,44 @@ int ttls_rsa_export_crt(const ttls_rsa_context *ctx, return 0; } -/* - * Initialize an RSA context - */ -void ttls_rsa_init(ttls_rsa_context *ctx, - int padding, - int hash_id) -{ - memset(ctx, 0, sizeof(ttls_rsa_context)); - - ttls_rsa_set_padding(ctx, padding, hash_id); - - spin_lock_init(&ctx->mutex); -} - -/* - * Set padding for an existing RSA context +/** + * Initialize an RSA context. + * + * TODO #1064: Set padding to #TTLS_RSA_PKCS_V21 for the RSAES-OAEP encryption + * scheme and the RSASSA-PSS signature scheme. The choice of padding mode is + * strictly enforced for private key operations, since there might be security + * concerns in mixing padding modes. For public key operations it is a default + * value, which can be overriden by calling specific rsa_rsaes_xxx or + * rsa_rsassa_xxx functions. + * + * The hash selected in hash_id is always used for OEAP encryption. For PSS + * signatures, it is always used for making signatures, but can be overriden + * for verifying them. If set to TTLS_MD_NONE, it is always overriden. */ -void ttls_rsa_set_padding(ttls_rsa_context *ctx, int padding, int hash_id) +void +ttls_rsa_init(ttls_rsa_context *ctx, int padding, int hash_id) { + /* + * TODO Select padding mode: TTLS_RSA_PKCS_V15 or TTLS_RSA_PKCS_V21. + */ ctx->padding = padding; + /* + * TODO The hash identifier of ttls_md_type_t type, if padding is + * TTLS_RSA_PKCS_V21. The hash_id parameter is ignored when using + * TTLS_RSA_PKCS_V15 padding. + */ ctx->hash_id = hash_id; + + spin_lock_init(&ctx->mutex); } -/* - * Get length in bytes of RSA modulus +/** + * Get length in bytes of RSA modulus. */ - -size_t ttls_rsa_get_len(const ttls_rsa_context *ctx) +size_t +ttls_rsa_get_len(const ttls_rsa_context *ctx) { - return(ctx->len); + return ctx->len; } @@ -2014,5 +2021,3 @@ void ttls_rsa_free(ttls_rsa_context *ctx) ttls_mpi_free(&ctx->DP); #endif /* TTLS_RSA_NO_CRT */ } - -#endif /* !TTLS_RSA_ALT */ diff --git a/tls/rsa.h b/tls/rsa.h index b9f2f7f97..0190e1e51 100644 --- a/tls/rsa.h +++ b/tls/rsa.h @@ -1,39 +1,34 @@ /** - * \file rsa.h + * Tempesta TLS * - * \brief The RSA public-key cryptosystem. + * The RSA public-key cryptosystem. * * For more information, see Public-Key Cryptography Standards (PKCS) * #1 v1.5: RSA Encryption and Public-Key Cryptography Standards * (PKCS) #1 v2.1: RSA Cryptography Specifications. * - */ -/* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved - * Copyright (C) 2015-2018 Tempesta Technologies, Inc. - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. + * SPDX-License-Identifier: GPL-2.0 * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This file is part of Mbed TLS (https://tls.mbed.org) + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TTLS_RSA_H #define TTLS_RSA_H -#include "config.h" +#include "crypto.h" #include "bignum.h" -#include "md.h" /* * RSA Error codes @@ -69,10 +64,6 @@ * eg for alternative (PKCS#11) RSA implemenations in the PK layers. */ -#if !defined(TTLS_RSA_ALT) -// Regular implementation -// - /** * \brief The RSA context structure. * @@ -108,42 +99,14 @@ typedef struct #TTLS_RSA_PKCS_V15 for 1.5 padding and #TTLS_RSA_PKCS_V21 for OAEP or PSS. */ int hash_id; /*!< Hash identifier of ttls_md_type_t type, - as specified in md.h for use in the MGF + as specified in crypto.h for use in the MGF mask generating function used in the EME-OAEP and EMSA-PSS encodings. */ spinlock_t mutex; /*!< Thread-safety mutex. */ } ttls_rsa_context; -/** - * \brief This function initializes an RSA context. - * - * \note Set padding to #TTLS_RSA_PKCS_V21 for the RSAES-OAEP - * encryption scheme and the RSASSA-PSS signature scheme. - * - * \param ctx The RSA context to initialize. - * \param padding Selects padding mode: #TTLS_RSA_PKCS_V15 or - * #TTLS_RSA_PKCS_V21. - * \param hash_id The hash identifier of #ttls_md_type_t type, if - * \p padding is #TTLS_RSA_PKCS_V21. - * - * \note The \p hash_id parameter is ignored when using - * #TTLS_RSA_PKCS_V15 padding. - * - * \note The choice of padding mode is strictly enforced for private key - * operations, since there might be security concerns in - * mixing padding modes. For public key operations it is - * a default value, which can be overriden by calling specific - * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. - * - * \note The hash selected in \p hash_id is always used for OEAP - * encryption. For PSS signatures, it is always used for - * making signatures, but can be overriden for verifying them. - * If set to #TTLS_MD_NONE, it is always overriden. - */ -void ttls_rsa_init(ttls_rsa_context *ctx, - int padding, - int hash_id); +void ttls_rsa_init(ttls_rsa_context *ctx, int padding, int hash_id); /** * \brief This function imports a set of core parameters into an @@ -359,18 +322,6 @@ int ttls_rsa_export_raw(const ttls_rsa_context *ctx, int ttls_rsa_export_crt(const ttls_rsa_context *ctx, ttls_mpi *DP, ttls_mpi *DQ, ttls_mpi *QP); -/** - * \brief This function sets padding for an already initialized RSA - * context. See ttls_rsa_init() for details. - * - * \param ctx The RSA context to be set. - * \param padding Selects padding mode: #TTLS_RSA_PKCS_V15 or - * #TTLS_RSA_PKCS_V21. - * \param hash_id The #TTLS_RSA_PKCS_V21 hash identifier. - */ -void ttls_rsa_set_padding(ttls_rsa_context *ctx, int padding, - int hash_id); - /** * \brief This function retrieves the length of RSA modulus in Bytes. * @@ -1034,8 +985,4 @@ int ttls_rsa_copy(ttls_rsa_context *dst, const ttls_rsa_context *src); */ void ttls_rsa_free(ttls_rsa_context *ctx); -#else /* TTLS_RSA_ALT */ -#include "rsa_alt.h" -#endif /* TTLS_RSA_ALT */ - #endif /* rsa.h */ diff --git a/tls/rsa_internal.h b/tls/rsa_internal.h index c68042808..5bb63721b 100644 --- a/tls/rsa_internal.h +++ b/tls/rsa_internal.h @@ -1,71 +1,52 @@ /** - * \file rsa_internal.h - * - * \brief Context-independent RSA helper functions - */ -/* - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: GPL-2.0 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * This file is part of mbed TLS (https://tls.mbed.org) - * - * - * This file declares some RSA-related helper functions useful when - * implementing the RSA interface. They are public and provided in a - * separate compilation unit in order to make it easy for designers of - * alternative RSA implementations to use them in their code, as it is - * conceived that the functionality they provide will be necessary - * for most complete implementations. - * - * End-users of Mbed TLS not intending to re-implement the RSA functionality - * are not expected to get into the need of making use of these functions directly, - * but instead should be able to use the functions declared in rsa.h. - * - * There are two classes of helper functions: - * (1) Parameter-generating helpers. These are: - * - ttls_rsa_deduce_primes - * - ttls_rsa_deduce_private_exponent - * - ttls_rsa_deduce_crt - * Each of these functions takes a set of core RSA parameters - * and generates some other, or CRT related parameters. - * (2) Parameter-checking helpers. These are: - * - ttls_rsa_validate_params - * - ttls_rsa_validate_crt - * They take a set of core or CRT related RSA parameters - * and check their validity. - * + * Tempesta TLS + * + * Context-independent RSA helper functions. + * + * This file declares some RSA-related helper functions useful when + * implementing the RSA interface. They are public and provided in a + * separate compilation unit in order to make it easy for designers of + * alternative RSA implementations to use them in their code, as it is + * conceived that the functionality they provide will be necessary + * for most complete implementations. + * + * There are two classes of helper functions: + * (1) Parameter-generating helpers. These are: + * - ttls_rsa_deduce_primes + * - ttls_rsa_deduce_private_exponent + * - ttls_rsa_deduce_crt + * Each of these functions takes a set of core RSA parameters + * and generates some other, or CRT related parameters. + * (2) Parameter-checking helpers. These are: + * - ttls_rsa_validate_params + * - ttls_rsa_validate_crt + * They take a set of core or CRT related RSA parameters + * and check their validity. + * + * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * Copyright (C) 2015-2019 Tempesta Technologies, Inc. + * SPDX-License-Identifier: GPL-2.0 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #ifndef TTLS_RSA_INTERNAL_H #define TTLS_RSA_INTERNAL_H -#if !defined(TTLS_CONFIG_FILE) #include "config.h" -#else -#include TTLS_CONFIG_FILE -#endif - #include "bignum.h" -#ifdef __cplusplus -extern "C" { -#endif - - /** * \brief Compute RSA prime moduli P, Q from public modulus N=PQ * and a pair of private and public key. diff --git a/tls/ssl_ticket.c b/tls/ssl_ticket.c index c9f92626b..90288abc3 100644 --- a/tls/ssl_ticket.c +++ b/tls/ssl_ticket.c @@ -98,7 +98,7 @@ int ttls_ticket_setup(ttls_ticket_context *ctx, ttls_cipher_type_t cipher, uint32_t lifetime) { int ret; - const ttls_cipher_info_t *cipher_info; + const TlsCipherInfo *cipher_info; ctx->ticket_lifetime = lifetime; @@ -388,9 +388,6 @@ int ttls_ticket_parse(void *p_ticket, key_name, 4 + 12 + 2, ticket, enc_len, ticket, &clear_len, tag, 16)) != 0) { - if (ret == TTLS_ERR_CIPHER_AUTH_FAILED) - ret = TTLS_ERR_INVALID_MAC; - goto cleanup; } if (clear_len != enc_len) diff --git a/tls/ssl_ticket.h b/tls/ssl_ticket.h index eb3ad6668..80dd1dcd1 100644 --- a/tls/ssl_ticket.h +++ b/tls/ssl_ticket.h @@ -28,7 +28,7 @@ * secrecy. */ -#include "cipher.h" +#include "crypto.h" #include "ttls.h" /** diff --git a/tls/tls_internal.h b/tls/tls_internal.h index 4e4f57568..a20ad1561 100644 --- a/tls/tls_internal.h +++ b/tls/tls_internal.h @@ -30,7 +30,7 @@ #include "lib/fsm.h" #include "lib/str.h" -#include "cipher.h" +#include "crypto.h" #include "ttls.h" /* Determine minimum supported version */ diff --git a/tls/tls_srv.c b/tls/tls_srv.c index d99ed81e4..369e9a746 100644 --- a/tls/tls_srv.c +++ b/tls/tls_srv.c @@ -550,15 +550,16 @@ ttls_choose_ciphersuite(TlsCtx *tls, const unsigned char *csp) } if (got_common_suite) { - T_DBG("got ciphersuites in common, but none of them usable\n"); + T_WARN("None of the common ciphersuites is usable" + " (e.g. no suitable certificate)\n"); ttls_send_alert(tls, TTLS_ALERT_LEVEL_FATAL, TTLS_ALERT_MSG_HANDSHAKE_FAILURE); - return TTLS_ERR_NO_USABLE_CIPHERSUITE; + return -EINVAL; } else { - T_DBG("got no ciphersuites in common\n"); + T_WARN("Got no ciphersuites in common\n"); ttls_send_alert(tls, TTLS_ALERT_LEVEL_FATAL, TTLS_ALERT_MSG_HANDSHAKE_FAILURE); - return TTLS_ERR_NO_CIPHER_CHOSEN; + return -EINVAL; } have_ciphersuite: @@ -1388,8 +1389,8 @@ ttls_write_server_key_exchange(TlsCtx *tls, struct sg_table *sgt, goto curve_matching_done; curve_matching_done: if (!curve || !*curve) { - T_DBG("no matching curve for ECDHE key exchange\n"); - r = TTLS_ERR_NO_CIPHER_CHOSEN; + T_WARN("No matching curve for ECDHE key exchange\n"); + r = -EINVAL; goto err; } T_DBG("ECDHE curve: %s\n", (*curve)->name); diff --git a/tls/ttls.c b/tls/ttls.c index b6fcde13e..01af45ec4 100644 --- a/tls/ttls.c +++ b/tls/ttls.c @@ -31,24 +31,19 @@ #include "lib/str.h" #include "config.h" #include "debug.h" -#include "md.h" +#include "crypto.h" #include "oid.h" #include "tls_internal.h" #include "ttls.h" MODULE_AUTHOR("Tempesta Technologies, Inc"); MODULE_DESCRIPTION("Tempesta TLS"); -MODULE_VERSION("0.2.1"); +MODULE_VERSION("0.2.2"); MODULE_LICENSE("GPL"); -typedef struct { - struct aead_request req; - char __ctx_reserved[8]; -} __attribute__((packed)) __TlsReq; +static DEFINE_PER_CPU(struct aead_request *, g_req) ____cacheline_aligned; -static DEFINE_PER_CPU(__TlsReq, g_req) ____cacheline_aligned; - -static struct kmem_cache *ttls_hs_cache; +static struct kmem_cache *ttls_hs_cache = NULL; static ttls_send_cb_t *ttls_send_cb; static inline unsigned short @@ -525,7 +520,7 @@ ttls_derive_keys(TlsCtx *tls) unsigned char keyblk[256] ____cacheline_aligned; unsigned char tmp[32]; unsigned char *key1, *key2, *mac_enc, *mac_dec; - const ttls_cipher_info_t *ci; + const TlsCipherInfo *ci; const TlsMdInfo *md_info; size_t mac_key_len, iv_copy_len; int r = 0, tag_size; @@ -633,7 +628,6 @@ ttls_derive_keys(TlsCtx *tls) if ((r = ttls_md_setup(&xfrm->md_ctx_enc, md_info, 1)) || (r = ttls_md_setup(&xfrm->md_ctx_dec, md_info, 1))) { - T_DBG("cannot setup hash context, %d\n", r); return r; } @@ -745,10 +739,10 @@ ttls_aead_req_alloc(struct crypto_aead *tfm) size_t need = sizeof(struct aead_request) + crypto_aead_reqsize(tfm); WARN_ON_ONCE(!in_serving_softirq()); - if (WARN_ON_ONCE(sizeof(__TlsReq) < need)) + if (WARN_ON_ONCE(ttls_aead_reqsize() < need)) return kzalloc(need, GFP_ATOMIC); - return &this_cpu_ptr(&g_req)->req; + return *this_cpu_ptr(&g_req); } static void @@ -756,10 +750,10 @@ ttls_aead_req_free(struct crypto_aead *tfm, struct aead_request *req) { size_t need = sizeof(struct aead_request) + crypto_aead_reqsize(tfm); - if (WARN_ON_ONCE(sizeof(__TlsReq) < need)) + if (WARN_ON_ONCE(ttls_aead_reqsize() < need)) kfree(req); else - bzero_fast(req, sizeof(__TlsReq)); + bzero_fast(req, ttls_aead_reqsize()); } /** @@ -786,11 +780,8 @@ ttls_encrypt(TlsCtx *tls, struct sg_table *sgt) struct aead_request *req; WARN_ON_ONCE(!ttls_xfrm_ready(tls)); - if (io->msglen > TLS_MAX_PAYLOAD_SIZE) { - T_DBG("%s record content %u too large, maximum %lu\n", - __func__, io->msglen, TLS_MAX_PAYLOAD_SIZE); - return TTLS_ERR_BAD_INPUT_DATA; - } + WARN_ON_ONCE(io->msglen > TLS_MAX_PAYLOAD_SIZE + TLS_MAX_OVERHEAD + - TLS_HEADER_SIZE); req = ttls_aead_req_alloc(c_ctx->cipher_ctx); if (unlikely(!req)) @@ -816,7 +807,7 @@ ttls_encrypt(TlsCtx *tls, struct sg_table *sgt) min_t(size_t, 256, io->msglen + TLS_HEADER_SIZE)); if ((r = crypto_aead_encrypt(req))) { - T_DBG2("encrypt failed: %d\n", r); + T_WARN("AEAD encryption failed: %d\n", r); goto err; } T_DBG3_SL("encrypted buf (first 64 bytes)", sgt->sgl, sgt->nents, 0, @@ -2413,9 +2404,39 @@ ttls_config_init(ttls_config *conf) } EXPORT_SYMBOL(ttls_config_init); -static int ssl_preset_suiteb_ciphersuites[] = { +static int ttls_default_ciphersuites[] = { + /* All AES-128 ephemeral suites */ TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + TTLS_TLS_DHE_RSA_WITH_AES_128_CCM, + TTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + TTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, + + /* All AES-256 ephemeral suites */ TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + TTLS_TLS_DHE_RSA_WITH_AES_256_CCM, + TTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + TTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, + + /* All AES-256 suites */ + TTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_RSA_WITH_AES_256_CCM, + TTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TTLS_TLS_RSA_WITH_AES_256_CCM_8, + + /* All AES-128 suites */ + TTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_RSA_WITH_AES_128_CCM, + TTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TTLS_TLS_RSA_WITH_AES_128_CCM_8, + 0 }; @@ -2468,11 +2489,8 @@ ttls_config_defaults(ttls_config *conf, int endpoint) conf->min_minor_ver = TTLS_MINOR_VERSION_3; /* TLS 1.2 */ conf->max_minor_ver = TTLS_MAX_MINOR_VERSION; - conf->ciphersuite_list[TTLS_MINOR_VERSION_0] - = conf->ciphersuite_list[TTLS_MINOR_VERSION_1] - = conf->ciphersuite_list[TTLS_MINOR_VERSION_2] - = conf->ciphersuite_list[TTLS_MINOR_VERSION_3] - = ssl_preset_suiteb_ciphersuites; + ttls_conf_ciphersuites_for_version(conf, ttls_default_ciphersuites, + TTLS_MINOR_VERSION_3); conf->cert_profile = &ttls_x509_crt_profile_suiteb; conf->sig_hashes = ssl_preset_suiteb_hashes; @@ -2757,26 +2775,16 @@ ttls_get_key_exchange_md_tls1_2(TlsCtx *tls, unsigned char *output, * ServerDHParams params; * }; */ - if ((r = ttls_md_setup(&ctx, md_info, 0))) { - T_DBG("cannot setup digest context, %d\n", r); + if ((r = ttls_md_setup(&ctx, md_info, 0))) goto exit; - } - if ((r = ttls_md_starts(&ctx))) { - T_DBG("cannot start digest context, %d\n", r); + if ((r = ttls_md_starts(&ctx))) goto exit; - } - if ((r = ttls_md_update(&ctx, tls->hs->randbytes, 64))) { - T_DBG("cannot update digest context for random, %d\n", r); + if ((r = ttls_md_update(&ctx, tls->hs->randbytes, 64))) goto exit; - } - if ((r = ttls_md_update(&ctx, data, data_len))) { - T_DBG("cannot update digest context for data, %d\n", r); + if ((r = ttls_md_update(&ctx, data, data_len))) goto exit; - } - if ((r = ttls_md_finish(&ctx, output))) { - T_DBG("cannot finish digest context, %d\n", r); + if ((r = ttls_md_finish(&ctx, output))) goto exit; - } exit: ttls_md_free(&ctx); @@ -2799,22 +2807,43 @@ ttls_time_debug(void) static void ttls_exit(void) { - ttls_mpi_modexit(); + int cpu; + kmem_cache_destroy(ttls_hs_cache); + + for_each_possible_cpu(cpu) { + struct aead_request **req = per_cpu_ptr(&g_req, cpu); + kfree(*req); + } + + ttls_mpi_modexit(); } static int __init ttls_init(void) { - int r; + int cpu, r; /* Bad configuration - protected record payload too large. */ BUILD_BUG_ON(TTLS_PAYLOAD_LEN > 16384 + 2048); if ((r = ttls_mpi_modinit())) return r; + + if ((r = ttls_crypto_modinit())) { + ttls_mpi_modexit(); + return r; + } + + for_each_possible_cpu(cpu) { + struct aead_request **req = per_cpu_ptr(&g_req, cpu); + *req = kmalloc(ttls_aead_reqsize(), GFP_KERNEL); + if (!*req) + goto err_free; + } + ttls_hs_cache = kmem_cache_create("ttls_hs_cache", sizeof(TlsHandshake), - 0, 0, NULL); + 0, 0, NULL); if (!ttls_hs_cache) goto err_free; diff --git a/tls/ttls.h b/tls/ttls.h index ec533a208..28a5d9352 100644 --- a/tls/ttls.h +++ b/tls/ttls.h @@ -51,8 +51,6 @@ #define TTLS_ERR_INVALID_RECORD -0x7200 /* The connection indicated an EOF. */ #define TTLS_ERR_CONN_EOF -0x7280 -/* The server has no ciphersuites in common with the client. */ -#define TTLS_ERR_NO_CIPHER_CHOSEN -0x7380 /* * No client certification received from the client, but required by the * authentication mode. @@ -110,11 +108,6 @@ #define TTLS_ERR_INTERNAL_ERROR -0x6C00 /* A buffer is too small to receive or write a message. */ #define TTLS_ERR_BUFFER_TOO_SMALL -0x6A00 -/* - * None of the common ciphersuites is usable (eg, no suitable certificate, - * see debug messages). - */ -#define TTLS_ERR_NO_USABLE_CIPHERSUITE -0x6980 /* Couldn't set the hash for verifying CertificateVerify. */ #define TTLS_ERR_INVALID_VERIFY_HASH -0x6600