From 4cc0cf8255a3726fe3f6cbbe1a877fe2fab7edc6 Mon Sep 17 00:00:00 2001 From: Ting Liu Date: Wed, 29 Jul 2015 18:11:18 -0300 Subject: openssl: rename to openssl-qoriq The QorIQ version of openssl needs to use another recipe name and have a common provider, which is than choosen for QorIQ-based machines. The recipe is now called 'openssl-qoriq' and it provides openssl so the preferrence is set just for QorIQ based machines. Signed-off-by: Ting Liu --- ...dd-support-for-aes-gcm-algorithm-offloadi.patch | 309 +++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 recipes-connectivity/openssl/openssl-qoriq/qoriq/0017-cryptodev-add-support-for-aes-gcm-algorithm-offloadi.patch (limited to 'recipes-connectivity/openssl/openssl-qoriq/qoriq/0017-cryptodev-add-support-for-aes-gcm-algorithm-offloadi.patch') diff --git a/recipes-connectivity/openssl/openssl-qoriq/qoriq/0017-cryptodev-add-support-for-aes-gcm-algorithm-offloadi.patch b/recipes-connectivity/openssl/openssl-qoriq/qoriq/0017-cryptodev-add-support-for-aes-gcm-algorithm-offloadi.patch new file mode 100644 index 0000000..bd9e61a --- /dev/null +++ b/recipes-connectivity/openssl/openssl-qoriq/qoriq/0017-cryptodev-add-support-for-aes-gcm-algorithm-offloadi.patch @@ -0,0 +1,309 @@ +From 11b55103463bac614e00d74e9f196ec4ec6bade1 Mon Sep 17 00:00:00 2001 +From: Cristian Stoica +Date: Mon, 16 Jun 2014 14:06:21 +0300 +Subject: [PATCH 17/26] cryptodev: add support for aes-gcm algorithm offloading + +Change-Id: I3b77dc5ef8b8f707309549244a02852d95b36168 +Signed-off-by: Cristian Stoica +Reviewed-on: http://git.am.freescale.net:8181/17226 +--- + apps/speed.c | 6 +- + crypto/engine/eng_cryptodev.c | 229 +++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 233 insertions(+), 2 deletions(-) + +diff --git a/apps/speed.c b/apps/speed.c +index 9886ca3..099dede 100644 +--- a/apps/speed.c ++++ b/apps/speed.c +@@ -224,7 +224,11 @@ + #endif + + #undef BUFSIZE +-#define BUFSIZE ((long)1024*8+1) ++/* The buffer overhead allows GCM tag at the end of the encrypted data. This ++ avoids buffer overflows from cryptodev since Linux kernel GCM ++ implementation allways adds the tag - unlike e_aes.c:aes_gcm_cipher() ++ which doesn't */ ++#define BUFSIZE ((long)1024*8 + EVP_GCM_TLS_TAG_LEN) + int run=0; + + static int mr=0; +diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c +index 13d924f..4493490 100644 +--- a/crypto/engine/eng_cryptodev.c ++++ b/crypto/engine/eng_cryptodev.c +@@ -78,8 +78,10 @@ struct dev_crypto_state { + struct session_op d_sess; + int d_fd; + unsigned char *aad; +- unsigned int aad_len; ++ int aad_len; + unsigned int len; ++ unsigned char *iv; ++ int ivlen; + + #ifdef USE_CRYPTODEV_DIGESTS + char dummy_mac_key[HASH_MAX_LEN]; +@@ -251,6 +253,7 @@ static struct { + { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, 0}, + { CRYPTO_TLS10_AES_CBC_HMAC_SHA1, NID_aes_128_cbc_hmac_sha1, 16, 16, 20}, + { CRYPTO_TLS10_AES_CBC_HMAC_SHA1, NID_aes_256_cbc_hmac_sha1, 16, 32, 20}, ++ { CRYPTO_AES_GCM, NID_aes_128_gcm, 16, 16, 0}, + { 0, NID_undef, 0, 0, 0}, + }; + +@@ -271,6 +274,19 @@ static struct { + }; + #endif + ++/* increment counter (64-bit int) by 1 */ ++static void ctr64_inc(unsigned char *counter) { ++ int n=8; ++ unsigned char c; ++ ++ do { ++ --n; ++ c = counter[n]; ++ ++c; ++ counter[n] = c; ++ if (c) return; ++ } while (n); ++} + /* + * Return a fd if /dev/crypto seems usable, 0 otherwise. + */ +@@ -762,6 +778,197 @@ static int cryptodev_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + } + } + ++static int cryptodev_init_gcm_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, const unsigned char *iv, int enc) ++{ ++ struct dev_crypto_state *state = ctx->cipher_data; ++ struct session_op *sess = &state->d_sess; ++ int cipher = -1, i; ++ if (!iv && !key) ++ return 1; ++ ++ if (iv) ++ memcpy(ctx->iv, iv, ctx->cipher->iv_len); ++ ++ for (i = 0; ciphers[i].id; i++) ++ if (ctx->cipher->nid == ciphers[i].nid && ++ ctx->cipher->iv_len <= ciphers[i].ivmax && ++ ctx->key_len == ciphers[i].keylen) { ++ cipher = ciphers[i].id; ++ break; ++ } ++ ++ if (!ciphers[i].id) { ++ state->d_fd = -1; ++ return 0; ++ } ++ ++ memset(sess, 0, sizeof(struct session_op)); ++ ++ if ((state->d_fd = get_dev_crypto()) < 0) ++ return 0; ++ ++ sess->key = (unsigned char *) key; ++ sess->keylen = ctx->key_len; ++ sess->cipher = cipher; ++ ++ if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { ++ put_dev_crypto(state->d_fd); ++ state->d_fd = -1; ++ return 0; ++ } ++ return 1; ++} ++ ++static int cryptodev_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ struct crypt_auth_op cryp = {0}; ++ struct dev_crypto_state *state = ctx->cipher_data; ++ struct session_op *sess = &state->d_sess; ++ int rv = len; ++ ++ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? ++ EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, ++ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) ++ return 0; ++ ++ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ out += EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ ++ if (ctx->encrypt) { ++ len -= EVP_GCM_TLS_TAG_LEN; ++ } ++ cryp.ses = sess->ses; ++ cryp.len = len; ++ cryp.src = (unsigned char*) in; ++ cryp.dst = out; ++ cryp.auth_src = state->aad; ++ cryp.auth_len = state->aad_len; ++ cryp.iv = ctx->iv; ++ cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; ++ ++ if (ioctl(state->d_fd, CIOCAUTHCRYPT, &cryp) == -1) { ++ return 0; ++ } ++ ++ if (ctx->encrypt) ++ ctr64_inc(state->iv + state->ivlen - 8); ++ else ++ rv = len - EVP_GCM_TLS_TAG_LEN; ++ ++ return rv; ++} ++ ++static int cryptodev_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ struct crypt_auth_op cryp; ++ struct dev_crypto_state *state = ctx->cipher_data; ++ struct session_op *sess = &state->d_sess; ++ ++ if (state->d_fd < 0) ++ return 0; ++ ++ if ((len % ctx->cipher->block_size) != 0) ++ return 0; ++ ++ if (state->aad_len >= 0) ++ return cryptodev_gcm_tls_cipher(ctx, out, in, len); ++ ++ memset(&cryp, 0, sizeof(cryp)); ++ ++ cryp.ses = sess->ses; ++ cryp.len = len; ++ cryp.src = (unsigned char*) in; ++ cryp.dst = out; ++ cryp.auth_src = NULL; ++ cryp.auth_len = 0; ++ cryp.iv = ctx->iv; ++ cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; ++ ++ if (ioctl(state->d_fd, CIOCAUTHCRYPT, &cryp) == -1) { ++ return 0; ++ } ++ ++ return len; ++} ++ ++static int cryptodev_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, ++ void *ptr) ++{ ++ struct dev_crypto_state *state = ctx->cipher_data; ++ switch (type) { ++ case EVP_CTRL_INIT: ++ { ++ state->ivlen = ctx->cipher->iv_len; ++ state->iv = ctx->iv; ++ state->aad_len = -1; ++ return 1; ++ } ++ case EVP_CTRL_GCM_SET_IV_FIXED: ++ { ++ /* Special case: -1 length restores whole IV */ ++ if (arg == -1) ++ { ++ memcpy(state->iv, ptr, state->ivlen); ++ return 1; ++ } ++ /* Fixed field must be at least 4 bytes and invocation field ++ * at least 8. ++ */ ++ if ((arg < 4) || (state->ivlen - arg) < 8) ++ return 0; ++ if (arg) ++ memcpy(state->iv, ptr, arg); ++ if (ctx->encrypt && ++ RAND_bytes(state->iv + arg, state->ivlen - arg) <= 0) ++ return 0; ++ return 1; ++ } ++ case EVP_CTRL_AEAD_TLS1_AAD: ++ { ++ unsigned int len; ++ if (arg != 13) ++ return 0; ++ ++ memcpy(ctx->buf, ptr, arg); ++ len=ctx->buf[arg-2] << 8 | ctx->buf[arg-1]; ++ ++ /* Correct length for explicit IV */ ++ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ ++ /* If decrypting correct for tag too */ ++ if (!ctx->encrypt) ++ len -= EVP_GCM_TLS_TAG_LEN; ++ ++ ctx->buf[arg-2] = len >> 8; ++ ctx->buf[arg-1] = len & 0xff; ++ ++ state->aad = ctx->buf; ++ state->aad_len = arg; ++ state->len = len; ++ ++ /* Extra padding: tag appended to record */ ++ return EVP_GCM_TLS_TAG_LEN; ++ } ++ case EVP_CTRL_GCM_SET_IV_INV: ++ { ++ if (ctx->encrypt) ++ return 0; ++ memcpy(state->iv + state->ivlen - arg, ptr, arg); ++ return 1; ++ } ++ case EVP_CTRL_GCM_IV_GEN: ++ if (arg <= 0 || arg > state->ivlen) ++ arg = state->ivlen; ++ memcpy(ptr, state->iv + state->ivlen - arg, arg); ++ return 1; ++ default: ++ return -1; ++ } ++} + /* + * libcrypto EVP stuff - this is how we get wired to EVP so the engine + * gets called when libcrypto requests a cipher NID. +@@ -901,6 +1108,23 @@ const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1 = { + cryptodev_cbc_hmac_sha1_ctrl, + NULL + }; ++ ++const EVP_CIPHER cryptodev_aes_128_gcm = { ++ NID_aes_128_gcm, ++ 1, 16, 12, ++ EVP_CIPH_GCM_MODE | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1 \ ++ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ ++ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT, ++ cryptodev_init_gcm_key, ++ cryptodev_gcm_cipher, ++ cryptodev_cleanup, ++ sizeof(struct dev_crypto_state), ++ EVP_CIPHER_set_asn1_iv, ++ EVP_CIPHER_get_asn1_iv, ++ cryptodev_gcm_ctrl, ++ NULL ++}; ++ + /* + * Registered by the ENGINE when used to find out how to deal with + * a particular NID in the ENGINE. this says what we'll do at the +@@ -944,6 +1168,9 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + case NID_aes_256_cbc_hmac_sha1: + *cipher = &cryptodev_aes_256_cbc_hmac_sha1; + break; ++ case NID_aes_128_gcm: ++ *cipher = &cryptodev_aes_128_gcm; ++ break; + default: + *cipher = NULL; + break; +-- +2.3.5 + -- cgit v1.2.3-54-g00ecf