Loading drivers/crypto/msm/qcrypto.c +398 −29 Original line number Diff line number Diff line Loading @@ -390,10 +390,9 @@ struct qcrypto_cipher_ctx { u8 ccm4309_nonce[QCRYPTO_CCM4309_NONCE_LEN]; union { struct crypto_ablkcipher *cipher_fb; struct crypto_aead *aead_fb; } fallback; struct crypto_ablkcipher *cipher_aes192_fb; struct crypto_ahash *ahash_aead_aes192_fb; }; struct qcrypto_resp_ctx { Loading Loading @@ -424,6 +423,17 @@ struct qcrypto_cipher_req_ctx { struct scatterlist ssg; /* Source Data sg */ unsigned char *data; /* Incoming data pointer*/ struct aead_request *aead_req; struct ahash_request *fb_hash_req; uint8_t fb_ahash_digest[SHA256_DIGEST_SIZE]; struct scatterlist fb_ahash_sg[3]; char *fb_ahash_assoc_iv; char *fb_aes_iv; unsigned int fb_ahash_length; struct ablkcipher_request *fb_aes_req; struct scatterlist *fb_aes_src; struct scatterlist *fb_aes_dst; unsigned int fb_aes_cryptlen; }; #define SHA_MAX_BLOCK_SIZE SHA256_BLOCK_SIZE Loading Loading @@ -873,15 +883,15 @@ static int _qcrypto_cra_aes_ablkcipher_init(struct crypto_tfm *tfm) struct crypto_priv *cp = &qcrypto_dev; if (cp->ce_support.use_sw_aes_cbc_ecb_ctr_algo) { ctx->fallback.cipher_fb = NULL; ctx->cipher_aes192_fb = NULL; return _qcrypto_cra_ablkcipher_init(tfm); } ctx->fallback.cipher_fb = crypto_alloc_ablkcipher(name, 0, ctx->cipher_aes192_fb = crypto_alloc_ablkcipher(name, 0, CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); if (IS_ERR(ctx->fallback.cipher_fb)) { if (IS_ERR(ctx->cipher_aes192_fb)) { pr_err("Error allocating fallback algo %s\n", name); ret = PTR_ERR(ctx->fallback.cipher_fb); ctx->fallback.cipher_fb = NULL; ret = PTR_ERR(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; return ret; } return _qcrypto_cra_ablkcipher_init(tfm); Loading Loading @@ -909,6 +919,68 @@ static int _qcrypto_cra_aead_sha256_init(struct crypto_tfm *tfm) return rc; } static int _qcrypto_cra_aead_aes_sha1_init(struct crypto_tfm *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_priv *cp = &qcrypto_dev; tfm->crt_aead.reqsize = sizeof(struct qcrypto_cipher_req_ctx); rc = _qcrypto_cipher_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; if (!cp->ce_support.aes_key_192) { ctx->cipher_aes192_fb = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); if (IS_ERR(ctx->cipher_aes192_fb)) { ctx->cipher_aes192_fb = NULL; } else { ctx->ahash_aead_aes192_fb = crypto_alloc_ahash( "hmac(sha1)", 0, 0); if (IS_ERR(ctx->ahash_aead_aes192_fb)) { ctx->ahash_aead_aes192_fb = NULL; crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } } } ctx->auth_alg = QCE_HASH_SHA1_HMAC; return 0; } static int _qcrypto_cra_aead_aes_sha256_init(struct crypto_tfm *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_priv *cp = &qcrypto_dev; tfm->crt_aead.reqsize = sizeof(struct qcrypto_cipher_req_ctx); rc = _qcrypto_cipher_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; if (!cp->ce_support.aes_key_192) { ctx->cipher_aes192_fb = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); if (IS_ERR(ctx->cipher_aes192_fb)) { ctx->cipher_aes192_fb = NULL; } else { ctx->ahash_aead_aes192_fb = crypto_alloc_ahash( "hmac(sha256)", 0, 0); if (IS_ERR(ctx->ahash_aead_aes192_fb)) { ctx->ahash_aead_aes192_fb = NULL; crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } } } ctx->auth_alg = QCE_HASH_SHA256_HMAC; return 0; } static int _qcrypto_cra_aead_ccm_init(struct crypto_tfm *tfm) { int rc; Loading Loading @@ -944,9 +1016,9 @@ static void _qcrypto_cra_aes_ablkcipher_exit(struct crypto_tfm *tfm) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); _qcrypto_cra_ablkcipher_exit(tfm); if (ctx->fallback.cipher_fb) crypto_free_ablkcipher(ctx->fallback.cipher_fb); ctx->fallback.cipher_fb = NULL; if (ctx->cipher_aes192_fb) crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } static void _qcrypto_cra_aead_exit(struct crypto_tfm *tfm) Loading @@ -955,7 +1027,21 @@ static void _qcrypto_cra_aead_exit(struct crypto_tfm *tfm) if (!list_empty(&ctx->rsp_queue)) pr_err("_qcrypto__cra_aead_exit: requests still outstanding"); }; } static void _qcrypto_cra_aead_aes_exit(struct crypto_tfm *tfm) { struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); if (!list_empty(&ctx->rsp_queue)) pr_err("_qcrypto__cra_aead_exit: requests still outstanding"); if (ctx->cipher_aes192_fb) crypto_free_ablkcipher(ctx->cipher_aes192_fb); if (ctx->ahash_aead_aes192_fb) crypto_free_ahash(ctx->ahash_aead_aes192_fb); ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; } static int _disp_stats(int id) { Loading Loading @@ -1195,10 +1281,10 @@ static int _qcrypto_setkey_aes_192_fallback(struct crypto_ablkcipher *cipher, int ret; ctx->enc_key_len = AES_KEYSIZE_192; ctx->fallback.cipher_fb->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ctx->fallback.cipher_fb->base.crt_flags |= ctx->cipher_aes192_fb->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ctx->cipher_aes192_fb->base.crt_flags |= (cipher->base.crt_flags & CRYPTO_TFM_REQ_MASK); ret = crypto_ablkcipher_setkey(ctx->fallback.cipher_fb, key, ret = crypto_ablkcipher_setkey(ctx->cipher_aes192_fb, key, AES_KEYSIZE_192); if (ret) { tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; Loading @@ -1219,7 +1305,7 @@ static int _qcrypto_setkey_aes(struct crypto_ablkcipher *cipher, const u8 *key, return 0; if ((len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) && ctx->cipher_aes192_fb) return _qcrypto_setkey_aes_192_fallback(cipher, key); if (_qcrypto_check_aes_keylen(cipher, cp, len)) { Loading Loading @@ -2392,7 +2478,7 @@ static int _qcrypto_enc_aes_192_fallback(struct ablkcipher_request *req) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); int err; ablkcipher_request_set_tfm(req, ctx->fallback.cipher_fb); ablkcipher_request_set_tfm(req, ctx->cipher_aes192_fb); err = crypto_ablkcipher_encrypt(req); ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); return err; Loading @@ -2405,7 +2491,7 @@ static int _qcrypto_dec_aes_192_fallback(struct ablkcipher_request *req) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); int err; ablkcipher_request_set_tfm(req, ctx->fallback.cipher_fb); ablkcipher_request_set_tfm(req, ctx->cipher_aes192_fb); err = crypto_ablkcipher_decrypt(req); ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); return err; Loading @@ -2429,7 +2515,7 @@ static int _qcrypto_enc_aes_ecb(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2459,7 +2545,7 @@ static int _qcrypto_enc_aes_cbc(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2489,7 +2575,7 @@ static int _qcrypto_enc_aes_ctr(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2673,7 +2759,7 @@ static int _qcrypto_dec_aes_ecb(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2703,7 +2789,7 @@ static int _qcrypto_dec_aes_cbc(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2733,7 +2819,7 @@ static int _qcrypto_dec_aes_ctr(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2955,6 +3041,7 @@ static int _qcrypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); struct rtattr *rta = (struct rtattr *)key; struct crypto_authenc_key_param *param; int ret; if (!RTA_OK(rta, keylen)) goto badkey; Loading @@ -2980,6 +3067,20 @@ static int _qcrypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, memcpy(ctx->enc_key, key + ctx->auth_key_len, ctx->enc_key_len); memcpy(ctx->auth_key, key, ctx->auth_key_len); if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) { crypto_ahash_clear_flags(ctx->ahash_aead_aes192_fb, ~0); ret = crypto_ahash_setkey(ctx->ahash_aead_aes192_fb, ctx->auth_key, ctx->auth_key_len); if (ret) goto badkey; crypto_ablkcipher_clear_flags(ctx->cipher_aes192_fb, ~0); ret = crypto_ablkcipher_setkey(ctx->cipher_aes192_fb, ctx->enc_key, ctx->enc_key_len); if (ret) goto badkey; } return 0; badkey: ctx->enc_key_len = 0; Loading Loading @@ -3029,6 +3130,253 @@ static int _qcrypto_aead_rfc4309_ccm_setkey(struct crypto_aead *aead, return ret; }; static void _qcrypto_aead_aes_192_fb_a_cb(struct qcrypto_cipher_req_ctx *rctx, int res) { struct aead_request *req; struct crypto_async_request *areq; req = rctx->aead_req; areq = &req->base; if (rctx->fb_aes_req) ablkcipher_request_free(rctx->fb_aes_req); if (rctx->fb_hash_req) ahash_request_free(rctx->fb_hash_req); rctx->fb_aes_req = NULL; rctx->fb_hash_req = NULL; kfree(rctx->fb_ahash_assoc_iv); kfree(rctx->fb_aes_iv); areq->complete(areq, res); } static void _aead_aes_fb_stage2_ahash_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); /* copy icv */ if (err == 0) scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _start_aead_aes_fb_stage2_hmac(struct qcrypto_cipher_req_ctx *rctx) { struct ahash_request *ahash_req; ahash_req = rctx->fb_hash_req; ahash_request_set_callback(ahash_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage2_ahash_complete, rctx); return crypto_ahash_digest(ahash_req); } static void _aead_aes_fb_stage2_decrypt_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; rctx = base->data; _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _start_aead_aes_fb_stage2_decrypt( struct qcrypto_cipher_req_ctx *rctx) { struct ablkcipher_request *aes_req; aes_req = rctx->fb_aes_req; ablkcipher_request_set_callback(aes_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage2_decrypt_complete, rctx); return crypto_ablkcipher_decrypt(aes_req); } static void _aead_aes_fb_stage1_ahash_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); /* compare icv */ if (err == 0) { unsigned char tmp[ctx->authsize]; scatterwalk_map_and_copy(tmp, req->src, req->cryptlen - ctx->authsize, ctx->authsize, 0); if (memcmp(rctx->fb_ahash_digest, tmp, ctx->authsize) != 0) err = -EBADMSG; } if (err) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); else { err = _start_aead_aes_fb_stage2_decrypt(rctx); if (err != -EINPROGRESS && err != -EBUSY) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } } static void _aead_aes_fb_stage1_encrypt_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); memcpy(ctx->iv, rctx->fb_aes_iv, rctx->ivsize); if (err) { _qcrypto_aead_aes_192_fb_a_cb(rctx, err); return; } err = _start_aead_aes_fb_stage2_hmac(rctx); /* copy icv */ if (err == 0) { scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); } if (err != -EINPROGRESS && err != -EBUSY) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _qcrypto_aead_aes_192_fallback(struct aead_request *req, bool is_encrypt) { struct qcrypto_cipher_req_ctx *rctx = aead_request_ctx(req); struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); struct crypto_aead *aead_tfm = crypto_aead_reqtfm(req); struct ablkcipher_request *aes_req = NULL; struct ahash_request *ahash_req = NULL; int rc = -EINVAL; int nbytes; int num_sg; rctx->fb_ahash_assoc_iv = NULL; rctx->fb_aes_iv = NULL; aes_req = ablkcipher_request_alloc(ctx->cipher_aes192_fb, GFP_KERNEL); if (!aes_req) return -ENOMEM; ahash_req = ahash_request_alloc(ctx->ahash_aead_aes192_fb, GFP_KERNEL); if (!ahash_req) goto ret; rctx->fb_aes_req = aes_req; rctx->fb_hash_req = ahash_req; rctx->aead_req = req; num_sg = qcrypto_count_sg(req->assoc, req->assoclen); rctx->fb_ahash_assoc_iv = kzalloc(req->assoclen + crypto_aead_ivsize(aead_tfm), GFP_ATOMIC); if (!rctx->fb_ahash_assoc_iv) goto ret; if (req->assoclen) qcrypto_sg_copy_to_buffer(req->assoc, num_sg, rctx->fb_ahash_assoc_iv, req->assoclen); memcpy(rctx->fb_ahash_assoc_iv + req->assoclen, req->iv, crypto_aead_ivsize(aead_tfm)); memset(rctx->fb_ahash_sg, 0, sizeof(rctx->fb_ahash_sg)); sg_set_buf(&rctx->fb_ahash_sg[0], rctx->fb_ahash_assoc_iv, req->assoclen + crypto_aead_ivsize(aead_tfm)); sg_mark_end(&rctx->fb_ahash_sg[1]); nbytes = req->cryptlen; if (is_encrypt) { sg_chain(&rctx->fb_ahash_sg[0], 2, req->dst); } else { sg_chain(&rctx->fb_ahash_sg[0], 2, req->src); nbytes -= ctx->authsize; } rctx->fb_ahash_length = nbytes + crypto_aead_ivsize(aead_tfm) + req->assoclen; rctx->fb_aes_src = req->src; rctx->fb_aes_dst = req->dst; rctx->fb_aes_cryptlen = nbytes; rctx->ivsize = crypto_aead_ivsize(aead_tfm); rctx->fb_aes_iv = kzalloc(rctx->ivsize, GFP_ATOMIC); if (!rctx->fb_aes_iv) goto ret; memcpy(rctx->fb_aes_iv, req->iv, rctx->ivsize); ablkcipher_request_set_crypt(aes_req, rctx->fb_aes_src, rctx->fb_aes_dst, rctx->fb_aes_cryptlen, rctx->fb_aes_iv); ahash_request_set_crypt(ahash_req, &rctx->fb_ahash_sg[0], rctx->fb_ahash_digest, rctx->fb_ahash_length); if (is_encrypt) { ablkcipher_request_set_callback(aes_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage1_encrypt_complete, rctx); rc = crypto_ablkcipher_encrypt(aes_req); if (rc == 0) { memcpy(ctx->iv, rctx->fb_aes_iv, rctx->ivsize); rc = _start_aead_aes_fb_stage2_hmac(rctx); if (rc == 0) { /* copy icv */ scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); } } if (rc == -EINPROGRESS || rc == -EBUSY) return rc; goto ret; } else { ahash_request_set_callback(ahash_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage1_ahash_complete, rctx); rc = crypto_ahash_digest(ahash_req); if (rc == 0) { unsigned char tmp[ctx->authsize]; /* compare icv */ scatterwalk_map_and_copy(tmp, req->src, req->cryptlen - ctx->authsize, ctx->authsize, 0); if (memcmp(rctx->fb_ahash_digest, tmp, ctx->authsize) != 0) rc = -EBADMSG; else rc = _start_aead_aes_fb_stage2_decrypt(rctx); } if (rc == -EINPROGRESS || rc == -EBUSY) return rc; goto ret; } ret: if (aes_req) ablkcipher_request_free(aes_req); if (ahash_req) ahash_request_free(ahash_req); kfree(rctx->fb_ahash_assoc_iv); kfree(rctx->fb_aes_iv); return rc; } static int _qcrypto_aead_encrypt_aes_cbc(struct aead_request *req) { struct qcrypto_cipher_req_ctx *rctx; Loading @@ -3049,10 +3397,14 @@ static int _qcrypto_aead_encrypt_aes_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_aes_enc++; else pstat->aead_sha256_aes_enc++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) return _qcrypto_aead_aes_192_fallback(req, true); return _qcrypto_queue_req(cp, ctx->pengine, &req->base); } Loading @@ -3075,11 +3427,16 @@ static int _qcrypto_aead_decrypt_aes_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_aes_dec++; else pstat->aead_sha256_aes_dec++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) return _qcrypto_aead_aes_192_fallback(req, false); return _qcrypto_queue_req(cp, ctx->pengine, &req->base); } Loading @@ -3100,6 +3457,7 @@ static int _qcrypto_aead_givencrypt_aes_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading @@ -3109,6 +3467,11 @@ static int _qcrypto_aead_givencrypt_aes_cbc(struct aead_givcrypt_request *req) pstat->aead_sha1_aes_enc++; else pstat->aead_sha256_aes_enc++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) { areq->iv = req->giv; return _qcrypto_aead_aes_192_fallback(areq, true); } return _qcrypto_queue_req(cp, ctx->pengine, &areq->base); } Loading @@ -3127,6 +3490,7 @@ static int _qcrypto_aead_encrypt_des_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_des_enc++; Loading @@ -3150,6 +3514,7 @@ static int _qcrypto_aead_decrypt_des_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_des_dec++; Loading @@ -3175,6 +3540,7 @@ static int _qcrypto_aead_givencrypt_des_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading @@ -3201,6 +3567,7 @@ static int _qcrypto_aead_encrypt_3des_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_3des_enc++; Loading @@ -3224,6 +3591,7 @@ static int _qcrypto_aead_decrypt_3des_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_3des_dec++; Loading @@ -3249,6 +3617,7 @@ static int _qcrypto_aead_givencrypt_3des_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading Loading @@ -4475,8 +4844,8 @@ static struct crypto_alg _qcrypto_aead_sha1_hmac_algos[] = { .cra_alignmask = 0, .cra_type = &crypto_aead_type, .cra_module = THIS_MODULE, .cra_init = _qcrypto_cra_aead_sha1_init, .cra_exit = _qcrypto_cra_aead_exit, .cra_init = _qcrypto_cra_aead_aes_sha1_init, .cra_exit = _qcrypto_cra_aead_aes_exit, .cra_u = { .aead = { .ivsize = AES_BLOCK_SIZE, Loading Loading @@ -4553,8 +4922,8 @@ static struct crypto_alg _qcrypto_aead_sha256_hmac_algos[] = { .cra_alignmask = 0, .cra_type = &crypto_aead_type, .cra_module = THIS_MODULE, .cra_init = _qcrypto_cra_aead_sha256_init, .cra_exit = _qcrypto_cra_aead_exit, .cra_init = _qcrypto_cra_aead_aes_sha256_init, .cra_exit = _qcrypto_cra_aead_aes_exit, .cra_u = { .aead = { .ivsize = AES_BLOCK_SIZE, Loading Loading
drivers/crypto/msm/qcrypto.c +398 −29 Original line number Diff line number Diff line Loading @@ -390,10 +390,9 @@ struct qcrypto_cipher_ctx { u8 ccm4309_nonce[QCRYPTO_CCM4309_NONCE_LEN]; union { struct crypto_ablkcipher *cipher_fb; struct crypto_aead *aead_fb; } fallback; struct crypto_ablkcipher *cipher_aes192_fb; struct crypto_ahash *ahash_aead_aes192_fb; }; struct qcrypto_resp_ctx { Loading Loading @@ -424,6 +423,17 @@ struct qcrypto_cipher_req_ctx { struct scatterlist ssg; /* Source Data sg */ unsigned char *data; /* Incoming data pointer*/ struct aead_request *aead_req; struct ahash_request *fb_hash_req; uint8_t fb_ahash_digest[SHA256_DIGEST_SIZE]; struct scatterlist fb_ahash_sg[3]; char *fb_ahash_assoc_iv; char *fb_aes_iv; unsigned int fb_ahash_length; struct ablkcipher_request *fb_aes_req; struct scatterlist *fb_aes_src; struct scatterlist *fb_aes_dst; unsigned int fb_aes_cryptlen; }; #define SHA_MAX_BLOCK_SIZE SHA256_BLOCK_SIZE Loading Loading @@ -873,15 +883,15 @@ static int _qcrypto_cra_aes_ablkcipher_init(struct crypto_tfm *tfm) struct crypto_priv *cp = &qcrypto_dev; if (cp->ce_support.use_sw_aes_cbc_ecb_ctr_algo) { ctx->fallback.cipher_fb = NULL; ctx->cipher_aes192_fb = NULL; return _qcrypto_cra_ablkcipher_init(tfm); } ctx->fallback.cipher_fb = crypto_alloc_ablkcipher(name, 0, ctx->cipher_aes192_fb = crypto_alloc_ablkcipher(name, 0, CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); if (IS_ERR(ctx->fallback.cipher_fb)) { if (IS_ERR(ctx->cipher_aes192_fb)) { pr_err("Error allocating fallback algo %s\n", name); ret = PTR_ERR(ctx->fallback.cipher_fb); ctx->fallback.cipher_fb = NULL; ret = PTR_ERR(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; return ret; } return _qcrypto_cra_ablkcipher_init(tfm); Loading Loading @@ -909,6 +919,68 @@ static int _qcrypto_cra_aead_sha256_init(struct crypto_tfm *tfm) return rc; } static int _qcrypto_cra_aead_aes_sha1_init(struct crypto_tfm *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_priv *cp = &qcrypto_dev; tfm->crt_aead.reqsize = sizeof(struct qcrypto_cipher_req_ctx); rc = _qcrypto_cipher_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; if (!cp->ce_support.aes_key_192) { ctx->cipher_aes192_fb = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); if (IS_ERR(ctx->cipher_aes192_fb)) { ctx->cipher_aes192_fb = NULL; } else { ctx->ahash_aead_aes192_fb = crypto_alloc_ahash( "hmac(sha1)", 0, 0); if (IS_ERR(ctx->ahash_aead_aes192_fb)) { ctx->ahash_aead_aes192_fb = NULL; crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } } } ctx->auth_alg = QCE_HASH_SHA1_HMAC; return 0; } static int _qcrypto_cra_aead_aes_sha256_init(struct crypto_tfm *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_priv *cp = &qcrypto_dev; tfm->crt_aead.reqsize = sizeof(struct qcrypto_cipher_req_ctx); rc = _qcrypto_cipher_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; if (!cp->ce_support.aes_key_192) { ctx->cipher_aes192_fb = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); if (IS_ERR(ctx->cipher_aes192_fb)) { ctx->cipher_aes192_fb = NULL; } else { ctx->ahash_aead_aes192_fb = crypto_alloc_ahash( "hmac(sha256)", 0, 0); if (IS_ERR(ctx->ahash_aead_aes192_fb)) { ctx->ahash_aead_aes192_fb = NULL; crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } } } ctx->auth_alg = QCE_HASH_SHA256_HMAC; return 0; } static int _qcrypto_cra_aead_ccm_init(struct crypto_tfm *tfm) { int rc; Loading Loading @@ -944,9 +1016,9 @@ static void _qcrypto_cra_aes_ablkcipher_exit(struct crypto_tfm *tfm) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); _qcrypto_cra_ablkcipher_exit(tfm); if (ctx->fallback.cipher_fb) crypto_free_ablkcipher(ctx->fallback.cipher_fb); ctx->fallback.cipher_fb = NULL; if (ctx->cipher_aes192_fb) crypto_free_ablkcipher(ctx->cipher_aes192_fb); ctx->cipher_aes192_fb = NULL; } static void _qcrypto_cra_aead_exit(struct crypto_tfm *tfm) Loading @@ -955,7 +1027,21 @@ static void _qcrypto_cra_aead_exit(struct crypto_tfm *tfm) if (!list_empty(&ctx->rsp_queue)) pr_err("_qcrypto__cra_aead_exit: requests still outstanding"); }; } static void _qcrypto_cra_aead_aes_exit(struct crypto_tfm *tfm) { struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); if (!list_empty(&ctx->rsp_queue)) pr_err("_qcrypto__cra_aead_exit: requests still outstanding"); if (ctx->cipher_aes192_fb) crypto_free_ablkcipher(ctx->cipher_aes192_fb); if (ctx->ahash_aead_aes192_fb) crypto_free_ahash(ctx->ahash_aead_aes192_fb); ctx->cipher_aes192_fb = NULL; ctx->ahash_aead_aes192_fb = NULL; } static int _disp_stats(int id) { Loading Loading @@ -1195,10 +1281,10 @@ static int _qcrypto_setkey_aes_192_fallback(struct crypto_ablkcipher *cipher, int ret; ctx->enc_key_len = AES_KEYSIZE_192; ctx->fallback.cipher_fb->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ctx->fallback.cipher_fb->base.crt_flags |= ctx->cipher_aes192_fb->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ctx->cipher_aes192_fb->base.crt_flags |= (cipher->base.crt_flags & CRYPTO_TFM_REQ_MASK); ret = crypto_ablkcipher_setkey(ctx->fallback.cipher_fb, key, ret = crypto_ablkcipher_setkey(ctx->cipher_aes192_fb, key, AES_KEYSIZE_192); if (ret) { tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; Loading @@ -1219,7 +1305,7 @@ static int _qcrypto_setkey_aes(struct crypto_ablkcipher *cipher, const u8 *key, return 0; if ((len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) && ctx->cipher_aes192_fb) return _qcrypto_setkey_aes_192_fallback(cipher, key); if (_qcrypto_check_aes_keylen(cipher, cp, len)) { Loading Loading @@ -2392,7 +2478,7 @@ static int _qcrypto_enc_aes_192_fallback(struct ablkcipher_request *req) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); int err; ablkcipher_request_set_tfm(req, ctx->fallback.cipher_fb); ablkcipher_request_set_tfm(req, ctx->cipher_aes192_fb); err = crypto_ablkcipher_encrypt(req); ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); return err; Loading @@ -2405,7 +2491,7 @@ static int _qcrypto_dec_aes_192_fallback(struct ablkcipher_request *req) struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); int err; ablkcipher_request_set_tfm(req, ctx->fallback.cipher_fb); ablkcipher_request_set_tfm(req, ctx->cipher_aes192_fb); err = crypto_ablkcipher_decrypt(req); ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); return err; Loading @@ -2429,7 +2515,7 @@ static int _qcrypto_enc_aes_ecb(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2459,7 +2545,7 @@ static int _qcrypto_enc_aes_cbc(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2489,7 +2575,7 @@ static int _qcrypto_enc_aes_ctr(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_enc_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2673,7 +2759,7 @@ static int _qcrypto_dec_aes_ecb(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2703,7 +2789,7 @@ static int _qcrypto_dec_aes_cbc(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2733,7 +2819,7 @@ static int _qcrypto_dec_aes_ctr(struct ablkcipher_request *req) if ((ctx->enc_key_len == AES_KEYSIZE_192) && (!cp->ce_support.aes_key_192) && ctx->fallback.cipher_fb) ctx->cipher_aes192_fb) return _qcrypto_dec_aes_192_fallback(req); rctx = ablkcipher_request_ctx(req); Loading Loading @@ -2955,6 +3041,7 @@ static int _qcrypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); struct rtattr *rta = (struct rtattr *)key; struct crypto_authenc_key_param *param; int ret; if (!RTA_OK(rta, keylen)) goto badkey; Loading @@ -2980,6 +3067,20 @@ static int _qcrypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, memcpy(ctx->enc_key, key + ctx->auth_key_len, ctx->enc_key_len); memcpy(ctx->auth_key, key, ctx->auth_key_len); if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) { crypto_ahash_clear_flags(ctx->ahash_aead_aes192_fb, ~0); ret = crypto_ahash_setkey(ctx->ahash_aead_aes192_fb, ctx->auth_key, ctx->auth_key_len); if (ret) goto badkey; crypto_ablkcipher_clear_flags(ctx->cipher_aes192_fb, ~0); ret = crypto_ablkcipher_setkey(ctx->cipher_aes192_fb, ctx->enc_key, ctx->enc_key_len); if (ret) goto badkey; } return 0; badkey: ctx->enc_key_len = 0; Loading Loading @@ -3029,6 +3130,253 @@ static int _qcrypto_aead_rfc4309_ccm_setkey(struct crypto_aead *aead, return ret; }; static void _qcrypto_aead_aes_192_fb_a_cb(struct qcrypto_cipher_req_ctx *rctx, int res) { struct aead_request *req; struct crypto_async_request *areq; req = rctx->aead_req; areq = &req->base; if (rctx->fb_aes_req) ablkcipher_request_free(rctx->fb_aes_req); if (rctx->fb_hash_req) ahash_request_free(rctx->fb_hash_req); rctx->fb_aes_req = NULL; rctx->fb_hash_req = NULL; kfree(rctx->fb_ahash_assoc_iv); kfree(rctx->fb_aes_iv); areq->complete(areq, res); } static void _aead_aes_fb_stage2_ahash_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); /* copy icv */ if (err == 0) scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _start_aead_aes_fb_stage2_hmac(struct qcrypto_cipher_req_ctx *rctx) { struct ahash_request *ahash_req; ahash_req = rctx->fb_hash_req; ahash_request_set_callback(ahash_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage2_ahash_complete, rctx); return crypto_ahash_digest(ahash_req); } static void _aead_aes_fb_stage2_decrypt_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; rctx = base->data; _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _start_aead_aes_fb_stage2_decrypt( struct qcrypto_cipher_req_ctx *rctx) { struct ablkcipher_request *aes_req; aes_req = rctx->fb_aes_req; ablkcipher_request_set_callback(aes_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage2_decrypt_complete, rctx); return crypto_ablkcipher_decrypt(aes_req); } static void _aead_aes_fb_stage1_ahash_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); /* compare icv */ if (err == 0) { unsigned char tmp[ctx->authsize]; scatterwalk_map_and_copy(tmp, req->src, req->cryptlen - ctx->authsize, ctx->authsize, 0); if (memcmp(rctx->fb_ahash_digest, tmp, ctx->authsize) != 0) err = -EBADMSG; } if (err) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); else { err = _start_aead_aes_fb_stage2_decrypt(rctx); if (err != -EINPROGRESS && err != -EBUSY) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } } static void _aead_aes_fb_stage1_encrypt_complete( struct crypto_async_request *base, int err) { struct qcrypto_cipher_req_ctx *rctx; struct aead_request *req; struct qcrypto_cipher_ctx *ctx; rctx = base->data; req = rctx->aead_req; ctx = crypto_tfm_ctx(req->base.tfm); memcpy(ctx->iv, rctx->fb_aes_iv, rctx->ivsize); if (err) { _qcrypto_aead_aes_192_fb_a_cb(rctx, err); return; } err = _start_aead_aes_fb_stage2_hmac(rctx); /* copy icv */ if (err == 0) { scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); } if (err != -EINPROGRESS && err != -EBUSY) _qcrypto_aead_aes_192_fb_a_cb(rctx, err); } static int _qcrypto_aead_aes_192_fallback(struct aead_request *req, bool is_encrypt) { struct qcrypto_cipher_req_ctx *rctx = aead_request_ctx(req); struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); struct crypto_aead *aead_tfm = crypto_aead_reqtfm(req); struct ablkcipher_request *aes_req = NULL; struct ahash_request *ahash_req = NULL; int rc = -EINVAL; int nbytes; int num_sg; rctx->fb_ahash_assoc_iv = NULL; rctx->fb_aes_iv = NULL; aes_req = ablkcipher_request_alloc(ctx->cipher_aes192_fb, GFP_KERNEL); if (!aes_req) return -ENOMEM; ahash_req = ahash_request_alloc(ctx->ahash_aead_aes192_fb, GFP_KERNEL); if (!ahash_req) goto ret; rctx->fb_aes_req = aes_req; rctx->fb_hash_req = ahash_req; rctx->aead_req = req; num_sg = qcrypto_count_sg(req->assoc, req->assoclen); rctx->fb_ahash_assoc_iv = kzalloc(req->assoclen + crypto_aead_ivsize(aead_tfm), GFP_ATOMIC); if (!rctx->fb_ahash_assoc_iv) goto ret; if (req->assoclen) qcrypto_sg_copy_to_buffer(req->assoc, num_sg, rctx->fb_ahash_assoc_iv, req->assoclen); memcpy(rctx->fb_ahash_assoc_iv + req->assoclen, req->iv, crypto_aead_ivsize(aead_tfm)); memset(rctx->fb_ahash_sg, 0, sizeof(rctx->fb_ahash_sg)); sg_set_buf(&rctx->fb_ahash_sg[0], rctx->fb_ahash_assoc_iv, req->assoclen + crypto_aead_ivsize(aead_tfm)); sg_mark_end(&rctx->fb_ahash_sg[1]); nbytes = req->cryptlen; if (is_encrypt) { sg_chain(&rctx->fb_ahash_sg[0], 2, req->dst); } else { sg_chain(&rctx->fb_ahash_sg[0], 2, req->src); nbytes -= ctx->authsize; } rctx->fb_ahash_length = nbytes + crypto_aead_ivsize(aead_tfm) + req->assoclen; rctx->fb_aes_src = req->src; rctx->fb_aes_dst = req->dst; rctx->fb_aes_cryptlen = nbytes; rctx->ivsize = crypto_aead_ivsize(aead_tfm); rctx->fb_aes_iv = kzalloc(rctx->ivsize, GFP_ATOMIC); if (!rctx->fb_aes_iv) goto ret; memcpy(rctx->fb_aes_iv, req->iv, rctx->ivsize); ablkcipher_request_set_crypt(aes_req, rctx->fb_aes_src, rctx->fb_aes_dst, rctx->fb_aes_cryptlen, rctx->fb_aes_iv); ahash_request_set_crypt(ahash_req, &rctx->fb_ahash_sg[0], rctx->fb_ahash_digest, rctx->fb_ahash_length); if (is_encrypt) { ablkcipher_request_set_callback(aes_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage1_encrypt_complete, rctx); rc = crypto_ablkcipher_encrypt(aes_req); if (rc == 0) { memcpy(ctx->iv, rctx->fb_aes_iv, rctx->ivsize); rc = _start_aead_aes_fb_stage2_hmac(rctx); if (rc == 0) { /* copy icv */ scatterwalk_map_and_copy(rctx->fb_ahash_digest, req->dst, req->cryptlen, ctx->authsize, 1); } } if (rc == -EINPROGRESS || rc == -EBUSY) return rc; goto ret; } else { ahash_request_set_callback(ahash_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _aead_aes_fb_stage1_ahash_complete, rctx); rc = crypto_ahash_digest(ahash_req); if (rc == 0) { unsigned char tmp[ctx->authsize]; /* compare icv */ scatterwalk_map_and_copy(tmp, req->src, req->cryptlen - ctx->authsize, ctx->authsize, 0); if (memcmp(rctx->fb_ahash_digest, tmp, ctx->authsize) != 0) rc = -EBADMSG; else rc = _start_aead_aes_fb_stage2_decrypt(rctx); } if (rc == -EINPROGRESS || rc == -EBUSY) return rc; goto ret; } ret: if (aes_req) ablkcipher_request_free(aes_req); if (ahash_req) ahash_request_free(ahash_req); kfree(rctx->fb_ahash_assoc_iv); kfree(rctx->fb_aes_iv); return rc; } static int _qcrypto_aead_encrypt_aes_cbc(struct aead_request *req) { struct qcrypto_cipher_req_ctx *rctx; Loading @@ -3049,10 +3397,14 @@ static int _qcrypto_aead_encrypt_aes_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_aes_enc++; else pstat->aead_sha256_aes_enc++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) return _qcrypto_aead_aes_192_fallback(req, true); return _qcrypto_queue_req(cp, ctx->pengine, &req->base); } Loading @@ -3075,11 +3427,16 @@ static int _qcrypto_aead_decrypt_aes_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_aes_dec++; else pstat->aead_sha256_aes_dec++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) return _qcrypto_aead_aes_192_fallback(req, false); return _qcrypto_queue_req(cp, ctx->pengine, &req->base); } Loading @@ -3100,6 +3457,7 @@ static int _qcrypto_aead_givencrypt_aes_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading @@ -3109,6 +3467,11 @@ static int _qcrypto_aead_givencrypt_aes_cbc(struct aead_givcrypt_request *req) pstat->aead_sha1_aes_enc++; else pstat->aead_sha256_aes_enc++; if (ctx->enc_key_len == AES_KEYSIZE_192 && ctx->cipher_aes192_fb && ctx->ahash_aead_aes192_fb) { areq->iv = req->giv; return _qcrypto_aead_aes_192_fallback(areq, true); } return _qcrypto_queue_req(cp, ctx->pengine, &areq->base); } Loading @@ -3127,6 +3490,7 @@ static int _qcrypto_aead_encrypt_des_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_des_enc++; Loading @@ -3150,6 +3514,7 @@ static int _qcrypto_aead_decrypt_des_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_des_dec++; Loading @@ -3175,6 +3540,7 @@ static int _qcrypto_aead_givencrypt_des_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading @@ -3201,6 +3567,7 @@ static int _qcrypto_aead_encrypt_3des_cbc(struct aead_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_3des_enc++; Loading @@ -3224,6 +3591,7 @@ static int _qcrypto_aead_decrypt_3des_cbc(struct aead_request *req) rctx->dir = QCE_DECRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->iv; rctx->aead_req = req; if (ctx->auth_alg == QCE_HASH_SHA1_HMAC) pstat->aead_sha1_3des_dec++; Loading @@ -3249,6 +3617,7 @@ static int _qcrypto_aead_givencrypt_3des_cbc(struct aead_givcrypt_request *req) rctx->dir = QCE_ENCRYPT; rctx->mode = QCE_MODE_CBC; rctx->iv = req->giv; /* generated iv */ rctx->aead_req = areq; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); /* avoid consecutive packets going out with same IV */ Loading Loading @@ -4475,8 +4844,8 @@ static struct crypto_alg _qcrypto_aead_sha1_hmac_algos[] = { .cra_alignmask = 0, .cra_type = &crypto_aead_type, .cra_module = THIS_MODULE, .cra_init = _qcrypto_cra_aead_sha1_init, .cra_exit = _qcrypto_cra_aead_exit, .cra_init = _qcrypto_cra_aead_aes_sha1_init, .cra_exit = _qcrypto_cra_aead_aes_exit, .cra_u = { .aead = { .ivsize = AES_BLOCK_SIZE, Loading Loading @@ -4553,8 +4922,8 @@ static struct crypto_alg _qcrypto_aead_sha256_hmac_algos[] = { .cra_alignmask = 0, .cra_type = &crypto_aead_type, .cra_module = THIS_MODULE, .cra_init = _qcrypto_cra_aead_sha256_init, .cra_exit = _qcrypto_cra_aead_exit, .cra_init = _qcrypto_cra_aead_aes_sha256_init, .cra_exit = _qcrypto_cra_aead_aes_exit, .cra_u = { .aead = { .ivsize = AES_BLOCK_SIZE, Loading