summaryrefslogtreecommitdiffstats
path: root/bsp/meta-freescale/recipes-connectivity/openssl/openssl-qoriq/0001-eng_devcrypto-add-support-for-TLS-algorithms-offload.patch
diff options
context:
space:
mode:
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.patch389
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
+