diff options
Diffstat (limited to 'bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch')
-rw-r--r-- | bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch b/bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch new file mode 100644 index 00000000..499df59b --- /dev/null +++ b/bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch @@ -0,0 +1,389 @@ +From 501988587567b996c9c4a14239f575e77ed27791 Mon Sep 17 00:00:00 2001 +From: Pankaj Gupta <pankaj.gupta@nxp.com> +Date: Fri, 20 Sep 2019 12:18:16 +0530 +Subject: [PATCH 1/2] eng_devcrypto: add support for TLS algorithms offload + + - aes-128-cbc-hmac-sha1 + - aes-256-cbc-hmac-sha1 + +Requires TLS patches on cryptodev and TLS algorithm support in Linux +kernel driver. + +Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com> +--- + crypto/engine/eng_devcrypto.c | 265 +++++++++++++++++++++++++++++----- + 1 file changed, 231 insertions(+), 34 deletions(-) + +diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c +index 49e9ce1af3..727a660e75 100644 +--- a/crypto/engine/eng_devcrypto.c ++++ b/crypto/engine/eng_devcrypto.c +@@ -60,6 +60,9 @@ struct cipher_ctx { + struct session_op sess; + int op; /* COP_ENCRYPT or COP_DECRYPT */ + unsigned long mode; /* EVP_CIPH_*_MODE */ ++ unsigned char *aad; ++ unsigned int aad_len; ++ unsigned int len; + + /* to handle ctr mode being a stream cipher */ + unsigned char partial[EVP_MAX_BLOCK_LENGTH]; +@@ -73,49 +76,62 @@ static const struct cipher_data_st { + int ivlen; + int flags; + int devcryptoid; ++ int mackeylen; + } cipher_data[] = { + #ifndef OPENSSL_NO_DES +- { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC }, +- { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC }, ++ { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC, 0 }, ++ { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC, 0 }, + #endif + #ifndef OPENSSL_NO_BF +- { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC }, ++ { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC, 0 }, + #endif + #ifndef OPENSSL_NO_CAST +- { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC }, ++ { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC, 0 }, + #endif +- { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, +- { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, +- { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, ++ { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 }, ++ { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 }, ++ { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 }, ++ { NID_aes_128_cbc_hmac_sha1, 16, 16, 16, ++ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER, ++ CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 }, ++ { NID_aes_256_cbc_hmac_sha1, 16, 32, 16, ++ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER, ++ CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 }, + #ifndef OPENSSL_NO_RC4 +- { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, ++ { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4, 0 }, + #endif + #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) +- { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, +- { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, +- { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, ++ { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 }, ++ { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 }, ++ { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 }, + #endif + #if 0 /* Not yet supported */ +- { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, +- { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, ++ { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS, ++ 0 }, ++ { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS, ++ 0 }, + #endif + #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB) +- { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, +- { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, +- { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, ++ { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 }, ++ { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 }, ++ { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 }, + #endif + #if 0 /* Not yet supported */ +- { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, +- { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, +- { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, ++ { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 }, ++ { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 }, ++ { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 }, ++#endif ++#ifdef OPENSSL_NXP_CAAM ++ { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 }, ++ { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 }, + #endif + #ifndef OPENSSL_NO_CAMELLIA + { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, +- CRYPTO_CAMELLIA_CBC }, ++ CRYPTO_CAMELLIA_CBC, 0 }, + { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, +- CRYPTO_CAMELLIA_CBC }, ++ CRYPTO_CAMELLIA_CBC, 0 }, + { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, +- CRYPTO_CAMELLIA_CBC }, ++ CRYPTO_CAMELLIA_CBC, 0 }, + #endif + }; + +@@ -141,6 +157,158 @@ static const struct cipher_data_st *get_cipher_data(int nid) + return &cipher_data[get_cipher_data_index(nid)]; + } + ++/* ++ * Save the encryption key provided by upper layers. This function is called ++ * by EVP_CipherInit_ex to initialize the algorithm's extra data. We can't do ++ * much here because the mac key is not available. The next call should/will ++ * be to cryptodev_cbc_hmac_sha1_ctrl with parameter ++ * EVP_CTRL_AEAD_SET_MAC_KEY, to set the hmac key. There we call CIOCGSESSION ++ * with both the crypto and hmac keys. ++ */ ++static int cryptodev_init_aead_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, const unsigned char *iv, int enc) ++{ ++ struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx); ++ struct session_op *sess = &state->sess; ++ int cipher = -1, i; ++ ++ for (i = 0; cipher_data[i].devcryptoid; i++) { ++ if (EVP_CIPHER_CTX_nid(ctx) == cipher_data[i].nid && ++ EVP_CIPHER_CTX_iv_length(ctx) <= cipher_data[i].ivlen && ++ EVP_CIPHER_CTX_key_length(ctx) == cipher_data[i].keylen) { ++ cipher = cipher_data[i].devcryptoid; ++ break; ++ } ++ } ++ ++ if (!cipher_data[i].devcryptoid) ++ return (0); ++ ++ memset(sess, 0, sizeof(*sess)); ++ ++ sess->key = (void *) key; ++ sess->keylen = EVP_CIPHER_CTX_key_length(ctx); ++ sess->cipher = cipher; ++ ++ /* for whatever reason, (1) means success */ ++ return 1; ++} ++ ++static int cryptodev_aead_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ struct crypt_auth_op cryp; ++ struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx); ++ struct session_op *sess = &state->sess; ++ const void *iiv; ++ unsigned char save_iv[EVP_MAX_IV_LENGTH]; ++ ++ if (cfd < 0) ++ return (0); ++ if (!len) ++ return (1); ++ if ((len % EVP_CIPHER_CTX_block_size(ctx)) != 0) ++ return (0); ++ ++ memset(&cryp, 0, sizeof(cryp)); ++ ++ /* TODO: make a seamless integration with cryptodev flags */ ++ switch (EVP_CIPHER_CTX_nid(ctx)) { ++ case NID_aes_128_cbc_hmac_sha1: ++ case NID_aes_256_cbc_hmac_sha1: ++ cryp.flags = COP_FLAG_AEAD_TLS_TYPE; ++ } ++ cryp.ses = sess->ses; ++ cryp.len = state->len; ++ cryp.src = (void *) in; ++ cryp.dst = (void *) out; ++ cryp.auth_src = state->aad; ++ cryp.auth_len = state->aad_len; ++ ++ cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT; ++ ++ if (EVP_CIPHER_CTX_iv_length(ctx) > 0) { ++ cryp.iv = (void *) EVP_CIPHER_CTX_iv(ctx); ++ if (!EVP_CIPHER_CTX_encrypting(ctx)) { ++ iiv = in + len - EVP_CIPHER_CTX_iv_length(ctx); ++ memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx)); ++ } ++ } else ++ cryp.iv = NULL; ++ ++ if (ioctl(cfd, CIOCAUTHCRYPT, &cryp) == -1) { ++ /* ++ * XXX need better errror handling this can fail for a number of ++ * different reasons. ++ */ ++ return 0; ++ } ++ ++ if (EVP_CIPHER_CTX_iv_length(ctx) > 0) { ++ if (EVP_CIPHER_CTX_encrypting(ctx)) ++ iiv = out + len - EVP_CIPHER_CTX_iv_length(ctx); ++ else ++ iiv = save_iv; ++ ++ memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv, ++ EVP_CIPHER_CTX_iv_length(ctx)); ++ } ++ return 1; ++} ++ ++static int cryptodev_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, ++ int arg, void *ptr) ++{ ++ switch (type) { ++ case EVP_CTRL_AEAD_SET_MAC_KEY: ++ { ++ /* TODO: what happens with hmac keys larger than 64 bytes? */ ++ struct cipher_ctx *state = ++ EVP_CIPHER_CTX_get_cipher_data(ctx); ++ struct session_op *sess = &state->sess; ++ ++ /* the rest should have been set in cryptodev_init_aead_key */ ++ sess->mackey = ptr; ++ sess->mackeylen = arg; ++ if (ioctl(cfd, CIOCGSESSION, sess) == -1) ++ return 0; ++ ++ return 1; ++ } ++ case EVP_CTRL_AEAD_TLS1_AAD: ++ { ++ /* ptr points to the associated data buffer of 13 bytes */ ++ struct cipher_ctx *state = ++ EVP_CIPHER_CTX_get_cipher_data(ctx); ++ unsigned char *p = ptr; ++ unsigned int cryptlen = p[arg - 2] << 8 | p[arg - 1]; ++ unsigned int maclen, padlen; ++ unsigned int bs = EVP_CIPHER_CTX_block_size(ctx); ++ ++ state->aad = ptr; ++ state->aad_len = arg; ++ state->len = cryptlen; ++ ++ /* TODO: this should be an extension of EVP_CIPHER struct */ ++ switch (EVP_CIPHER_CTX_nid(ctx)) { ++ case NID_aes_128_cbc_hmac_sha1: ++ case NID_aes_256_cbc_hmac_sha1: ++ maclen = SHA_DIGEST_LENGTH; ++ } ++ ++ /* space required for encryption (not only TLS padding) */ ++ padlen = maclen; ++ if (EVP_CIPHER_CTX_encrypting(ctx)) { ++ cryptlen += maclen; ++ padlen += bs - (cryptlen % bs); ++ } ++ return padlen; ++ } ++ default: ++ return -1; ++ } ++} ++ + /* + * Following are the three necessary functions to map OpenSSL functionality + * with cryptodev. +@@ -165,6 +333,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; + cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; + cipher_ctx->blocksize = cipher_d->blocksize; ++ + if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { + SYSerr(SYS_F_IOCTL, errno); + return 0; +@@ -180,6 +349,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); + struct crypt_op cryp; + unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); ++ + #if !defined(COP_FLAG_WRITE_IV) + unsigned char saved_iv[EVP_MAX_IV_LENGTH]; + const unsigned char *ivptr; +@@ -340,32 +510,59 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx) + static int known_cipher_nids[OSSL_NELEM(cipher_data)]; + static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ + static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; ++int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc); ++int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl); ++int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); + + static void prepare_cipher_methods(void) + { + size_t i; + struct session_op sess; + unsigned long cipher_mode; ++ unsigned long flags; + + memset(&sess, 0, sizeof(sess)); + sess.key = (void *)"01234567890123456789012345678901234567890123456789"; ++ sess.mackey = (void *)"123456789ABCDEFGHIJKLMNO"; + + for (i = 0, known_cipher_nids_amount = 0; + i < OSSL_NELEM(cipher_data); i++) { + ++ init = cipher_init; ++ ctrl = cipher_ctrl; ++ flags = cipher_data[i].flags ++ | EVP_CIPH_CUSTOM_COPY ++ | EVP_CIPH_CTRL_INIT ++ | EVP_CIPH_FLAG_DEFAULT_ASN1; ++ + /* + * Check that the algo is really availably by trying to open and close + * a session. + */ + sess.cipher = cipher_data[i].devcryptoid; + sess.keylen = cipher_data[i].keylen; ++ sess.mackeylen = cipher_data[i].mackeylen; ++ ++ cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; ++ ++ do_cipher = (cipher_mode == EVP_CIPH_CTR_MODE ? ++ ctr_do_cipher : ++ cipher_do_cipher); ++ if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1 ++ || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1) { ++ init = cryptodev_init_aead_key; ++ do_cipher = cryptodev_aead_cipher; ++ ctrl = cryptodev_cbc_hmac_sha1_ctrl; ++ flags = cipher_data[i].flags; ++ } ++ + if (ioctl(cfd, CIOCGSESSION, &sess) < 0 + || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0) + continue; + +- cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; +- +- if ((known_cipher_methods[i] = ++ if ((known_cipher_methods[i] = + EVP_CIPHER_meth_new(cipher_data[i].nid, + cipher_mode == EVP_CIPH_CTR_MODE ? 1 : + cipher_data[i].blocksize, +@@ -373,16 +570,12 @@ static void prepare_cipher_methods(void) + || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], + cipher_data[i].ivlen) + || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], +- cipher_data[i].flags +- | EVP_CIPH_CUSTOM_COPY +- | EVP_CIPH_CTRL_INIT +- | EVP_CIPH_FLAG_DEFAULT_ASN1) +- || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) ++ flags) ++ || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], init) + || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], +- cipher_mode == EVP_CIPH_CTR_MODE ? +- ctr_do_cipher : +- cipher_do_cipher) +- || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) ++ do_cipher) ++ /* AEAD Support to be added. */ ++ || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], ctrl) + || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], + cipher_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], +@@ -393,6 +586,10 @@ static void prepare_cipher_methods(void) + known_cipher_nids[known_cipher_nids_amount++] = + cipher_data[i].nid; + } ++ ++ if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1 ++ || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1) ++ EVP_add_cipher(known_cipher_methods[i]); + } + } + +-- +2.17.1 + |