static int crypto4xx_setup_fallback(struct crypto4xx_ctx *ctx, struct crypto_aead *cipher, const u8 *key, unsigned int keylen) { int rc; crypto_aead_clear_flags(ctx->sw_cipher.aead, CRYPTO_TFM_REQ_MASK); crypto_aead_set_flags(ctx->sw_cipher.aead, crypto_aead_get_flags(cipher) & CRYPTO_TFM_REQ_MASK); rc = crypto_aead_setkey(ctx->sw_cipher.aead, key, keylen); crypto_aead_clear_flags(cipher, CRYPTO_TFM_RES_MASK); crypto_aead_set_flags(cipher, crypto_aead_get_flags(ctx->sw_cipher.aead) & CRYPTO_TFM_RES_MASK); return rc; }
static int simd_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int key_len) { struct simd_aead_ctx *ctx = crypto_aead_ctx(tfm); struct crypto_aead *child = &ctx->cryptd_tfm->base; int err; crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK); crypto_aead_set_flags(child, crypto_aead_get_flags(tfm) & CRYPTO_TFM_REQ_MASK); err = crypto_aead_setkey(child, key, key_len); crypto_aead_set_flags(tfm, crypto_aead_get_flags(child) & CRYPTO_TFM_RES_MASK); return err; }
static int crypto_rfc4309_setkey(struct crypto_aead *parent, const u8 *key, unsigned int keylen) { struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent); struct crypto_aead *child = ctx->child; int err; if (keylen < 3) return -EINVAL; keylen -= 3; memcpy(ctx->nonce, key + keylen, 3); crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK); crypto_aead_set_flags(child, crypto_aead_get_flags(parent) & CRYPTO_TFM_REQ_MASK); err = crypto_aead_setkey(child, key, keylen); crypto_aead_set_flags(parent, crypto_aead_get_flags(child) & CRYPTO_TFM_RES_MASK); return err; }
/* * AEAD algorithm self tests */ int _fips_qcrypto_aead_selftest(struct fips_selftest_data *selftest_d) { int rc = 0, err, tv_index, num_tv, authsize, buf_length; struct crypto_aead *tfm; struct aead_request *aead_req; struct _fips_completion fips_completion; struct scatterlist fips_sg, fips_assoc_sg; char *k_align_src = NULL; struct _fips_test_vector_aead tv_aead; num_tv = (sizeof(fips_test_vector_aead)) / (sizeof(struct _fips_test_vector_aead)); /* One-by-one testing */ for (tv_index = 0; tv_index < num_tv; tv_index++) { memcpy(&tv_aead, &fips_test_vector_aead[tv_index], (sizeof(struct _fips_test_vector_aead))); if (tv_aead.pln_txt_len > tv_aead.enc_txt_len) buf_length = tv_aead.pln_txt_len; else buf_length = tv_aead.enc_txt_len; /* Single buffer allocation for in place operation */ k_align_src = kzalloc(buf_length, GFP_KERNEL); if (k_align_src == NULL) { pr_err("qcrypto:, Failed to allocate memory for k_align_src %ld\n", PTR_ERR(k_align_src)); return -ENOMEM; } memcpy(&k_align_src[0], tv_aead.pln_txt, tv_aead.pln_txt_len); /* use_sw flags are set in dtsi file which makes default Linux API calls to go to s/w crypto instead of h/w crypto. This code makes sure that all selftests calls always go to h/w, independent of DTSI flags. */ if (selftest_d->prefix_aead_algo) { if (_fips_get_alg_cra_name(tv_aead.mod_alg, selftest_d->algo_prefix, strlen(tv_aead.mod_alg))) { rc = -1; pr_err("Algo Name is too long for tv %d\n", tv_index); goto clr_buf; } } tfm = crypto_alloc_aead(tv_aead.mod_alg, 0, 0); if (IS_ERR(tfm)) { pr_err("qcrypto: %s algorithm not found\n", tv_aead.mod_alg); rc = -ENOMEM; goto clr_buf; } aead_req = aead_request_alloc(tfm, GFP_KERNEL); if (!aead_req) { pr_err("qcrypto:aead_request_alloc failed\n"); rc = -ENOMEM; goto clr_tfm; } rc = qcrypto_aead_set_device(aead_req, selftest_d->ce_device); if (rc != 0) { pr_err("%s qcrypto_cipher_set_device failed with err %d\n", __func__, rc); goto clr_aead_req; } init_completion(&fips_completion.completion); aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _fips_cb, &fips_completion); crypto_aead_clear_flags(tfm, ~0); rc = crypto_aead_setkey(tfm, tv_aead.key, tv_aead.klen); if (rc) { pr_err("qcrypto:crypto_aead_setkey failed\n"); goto clr_aead_req; } authsize = abs(tv_aead.enc_txt_len - tv_aead.pln_txt_len); rc = crypto_aead_setauthsize(tfm, authsize); if (rc) { pr_err("qcrypto:crypto_aead_setauthsize failed\n"); goto clr_aead_req; } sg_init_one(&fips_sg, k_align_src, tv_aead.pln_txt_len + authsize); aead_request_set_crypt(aead_req, &fips_sg, &fips_sg, tv_aead.pln_txt_len , tv_aead.iv); sg_init_one(&fips_assoc_sg, tv_aead.assoc, tv_aead.alen); aead_request_set_assoc(aead_req, &fips_assoc_sg, tv_aead.alen); /**** Encryption test ****/ rc = crypto_aead_encrypt(aead_req); if (rc == -EINPROGRESS || rc == -EBUSY) { rc = wait_for_completion_interruptible( &fips_completion.completion); err = fips_completion.err; if (!rc && !err) { INIT_COMPLETION(fips_completion.completion); } else { pr_err("qcrypto:aead:ENC, wait_for_completion failed\n"); goto clr_aead_req; } } if (memcmp(k_align_src, tv_aead.enc_txt, tv_aead.enc_txt_len)) { rc = -1; goto clr_aead_req; } /** Decryption test **/ init_completion(&fips_completion.completion); aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, _fips_cb, &fips_completion); crypto_aead_clear_flags(tfm, ~0); rc = crypto_aead_setkey(tfm, tv_aead.key, tv_aead.klen); if (rc) { pr_err("qcrypto:aead:DEC, crypto_aead_setkey failed\n"); goto clr_aead_req; } authsize = abs(tv_aead.enc_txt_len - tv_aead.pln_txt_len); rc = crypto_aead_setauthsize(tfm, authsize); if (rc) { pr_err("qcrypto:aead:DEC, crypto_aead_setauthsize failed\n"); goto clr_aead_req; } sg_init_one(&fips_sg, k_align_src, tv_aead.enc_txt_len + authsize); aead_request_set_crypt(aead_req, &fips_sg, &fips_sg, tv_aead.enc_txt_len, tv_aead.iv); sg_init_one(&fips_assoc_sg, tv_aead.assoc, tv_aead.alen); aead_request_set_assoc(aead_req, &fips_assoc_sg, tv_aead.alen); rc = crypto_aead_decrypt(aead_req); if (rc == -EINPROGRESS || rc == -EBUSY) { rc = wait_for_completion_interruptible( &fips_completion.completion); err = fips_completion.err; if (!rc && !err) { INIT_COMPLETION(fips_completion.completion); } else { pr_err("qcrypto:aead:DEC, wait_for_completion failed\n"); goto clr_aead_req; } } if (memcmp(k_align_src, tv_aead.pln_txt, tv_aead.pln_txt_len)) { rc = -1; goto clr_aead_req; } clr_aead_req: aead_request_free(aead_req); clr_tfm: crypto_free_aead(tfm); clr_buf: kzfree(k_align_src); /* In case of any failure, return error */ if (rc) return rc; } return rc; }