18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ESSIV skcipher and aead template for block encryption 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This template encapsulates the ESSIV IV generation algorithm used by 68c2ecf20Sopenharmony_ci * dm-crypt and fscrypt, which converts the initial vector for the skcipher 78c2ecf20Sopenharmony_ci * used for block encryption, by encrypting it using the hash of the 88c2ecf20Sopenharmony_ci * skcipher key as encryption key. Usually, the input IV is a 64-bit sector 98c2ecf20Sopenharmony_ci * number in LE representation zero-padded to the size of the IV, but this 108c2ecf20Sopenharmony_ci * is not assumed by this driver. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * The typical use of this template is to instantiate the skcipher 138c2ecf20Sopenharmony_ci * 'essiv(cbc(aes),sha256)', which is the only instantiation used by 148c2ecf20Sopenharmony_ci * fscrypt, and the most relevant one for dm-crypt. However, dm-crypt 158c2ecf20Sopenharmony_ci * also permits ESSIV to be used in combination with the authenc template, 168c2ecf20Sopenharmony_ci * e.g., 'essiv(authenc(hmac(sha256),cbc(aes)),sha256)', in which case 178c2ecf20Sopenharmony_ci * we need to instantiate an aead that accepts the same special key format 188c2ecf20Sopenharmony_ci * as the authenc template, and deals with the way the encrypted IV is 198c2ecf20Sopenharmony_ci * embedded into the AAD area of the aead request. This means the AEAD 208c2ecf20Sopenharmony_ci * flavor produced by this template is tightly coupled to the way dm-crypt 218c2ecf20Sopenharmony_ci * happens to use it. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Copyright (c) 2019 Linaro, Ltd. <ard.biesheuvel@linaro.org> 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * Heavily based on: 268c2ecf20Sopenharmony_ci * adiantum length-preserving encryption mode 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * Copyright 2018 Google LLC 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <crypto/authenc.h> 328c2ecf20Sopenharmony_ci#include <crypto/internal/aead.h> 338c2ecf20Sopenharmony_ci#include <crypto/internal/hash.h> 348c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h> 358c2ecf20Sopenharmony_ci#include <crypto/scatterwalk.h> 368c2ecf20Sopenharmony_ci#include <linux/module.h> 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#include "internal.h" 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistruct essiv_instance_ctx { 418c2ecf20Sopenharmony_ci union { 428c2ecf20Sopenharmony_ci struct crypto_skcipher_spawn skcipher_spawn; 438c2ecf20Sopenharmony_ci struct crypto_aead_spawn aead_spawn; 448c2ecf20Sopenharmony_ci } u; 458c2ecf20Sopenharmony_ci char essiv_cipher_name[CRYPTO_MAX_ALG_NAME]; 468c2ecf20Sopenharmony_ci char shash_driver_name[CRYPTO_MAX_ALG_NAME]; 478c2ecf20Sopenharmony_ci}; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistruct essiv_tfm_ctx { 508c2ecf20Sopenharmony_ci union { 518c2ecf20Sopenharmony_ci struct crypto_skcipher *skcipher; 528c2ecf20Sopenharmony_ci struct crypto_aead *aead; 538c2ecf20Sopenharmony_ci } u; 548c2ecf20Sopenharmony_ci struct crypto_cipher *essiv_cipher; 558c2ecf20Sopenharmony_ci struct crypto_shash *hash; 568c2ecf20Sopenharmony_ci int ivoffset; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistruct essiv_aead_request_ctx { 608c2ecf20Sopenharmony_ci struct scatterlist sg[4]; 618c2ecf20Sopenharmony_ci u8 *assoc; 628c2ecf20Sopenharmony_ci struct aead_request aead_req; 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic int essiv_skcipher_setkey(struct crypto_skcipher *tfm, 668c2ecf20Sopenharmony_ci const u8 *key, unsigned int keylen) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); 698c2ecf20Sopenharmony_ci u8 salt[HASH_MAX_DIGESTSIZE]; 708c2ecf20Sopenharmony_ci int err; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci crypto_skcipher_clear_flags(tctx->u.skcipher, CRYPTO_TFM_REQ_MASK); 738c2ecf20Sopenharmony_ci crypto_skcipher_set_flags(tctx->u.skcipher, 748c2ecf20Sopenharmony_ci crypto_skcipher_get_flags(tfm) & 758c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 768c2ecf20Sopenharmony_ci err = crypto_skcipher_setkey(tctx->u.skcipher, key, keylen); 778c2ecf20Sopenharmony_ci if (err) 788c2ecf20Sopenharmony_ci return err; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci err = crypto_shash_tfm_digest(tctx->hash, key, keylen, salt); 818c2ecf20Sopenharmony_ci if (err) 828c2ecf20Sopenharmony_ci return err; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci crypto_cipher_clear_flags(tctx->essiv_cipher, CRYPTO_TFM_REQ_MASK); 858c2ecf20Sopenharmony_ci crypto_cipher_set_flags(tctx->essiv_cipher, 868c2ecf20Sopenharmony_ci crypto_skcipher_get_flags(tfm) & 878c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 888c2ecf20Sopenharmony_ci return crypto_cipher_setkey(tctx->essiv_cipher, salt, 898c2ecf20Sopenharmony_ci crypto_shash_digestsize(tctx->hash)); 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic int essiv_aead_setkey(struct crypto_aead *tfm, const u8 *key, 938c2ecf20Sopenharmony_ci unsigned int keylen) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); 968c2ecf20Sopenharmony_ci SHASH_DESC_ON_STACK(desc, tctx->hash); 978c2ecf20Sopenharmony_ci struct crypto_authenc_keys keys; 988c2ecf20Sopenharmony_ci u8 salt[HASH_MAX_DIGESTSIZE]; 998c2ecf20Sopenharmony_ci int err; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci crypto_aead_clear_flags(tctx->u.aead, CRYPTO_TFM_REQ_MASK); 1028c2ecf20Sopenharmony_ci crypto_aead_set_flags(tctx->u.aead, crypto_aead_get_flags(tfm) & 1038c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 1048c2ecf20Sopenharmony_ci err = crypto_aead_setkey(tctx->u.aead, key, keylen); 1058c2ecf20Sopenharmony_ci if (err) 1068c2ecf20Sopenharmony_ci return err; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) 1098c2ecf20Sopenharmony_ci return -EINVAL; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci desc->tfm = tctx->hash; 1128c2ecf20Sopenharmony_ci err = crypto_shash_init(desc) ?: 1138c2ecf20Sopenharmony_ci crypto_shash_update(desc, keys.enckey, keys.enckeylen) ?: 1148c2ecf20Sopenharmony_ci crypto_shash_finup(desc, keys.authkey, keys.authkeylen, salt); 1158c2ecf20Sopenharmony_ci if (err) 1168c2ecf20Sopenharmony_ci return err; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci crypto_cipher_clear_flags(tctx->essiv_cipher, CRYPTO_TFM_REQ_MASK); 1198c2ecf20Sopenharmony_ci crypto_cipher_set_flags(tctx->essiv_cipher, crypto_aead_get_flags(tfm) & 1208c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 1218c2ecf20Sopenharmony_ci return crypto_cipher_setkey(tctx->essiv_cipher, salt, 1228c2ecf20Sopenharmony_ci crypto_shash_digestsize(tctx->hash)); 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic int essiv_aead_setauthsize(struct crypto_aead *tfm, 1268c2ecf20Sopenharmony_ci unsigned int authsize) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci return crypto_aead_setauthsize(tctx->u.aead, authsize); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic void essiv_skcipher_done(struct crypto_async_request *areq, int err) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci struct skcipher_request *req = areq->data; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci skcipher_request_complete(req, err); 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic int essiv_skcipher_crypt(struct skcipher_request *req, bool enc) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1438c2ecf20Sopenharmony_ci const struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); 1448c2ecf20Sopenharmony_ci struct skcipher_request *subreq = skcipher_request_ctx(req); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci skcipher_request_set_tfm(subreq, tctx->u.skcipher); 1498c2ecf20Sopenharmony_ci skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 1508c2ecf20Sopenharmony_ci req->iv); 1518c2ecf20Sopenharmony_ci skcipher_request_set_callback(subreq, skcipher_request_flags(req), 1528c2ecf20Sopenharmony_ci essiv_skcipher_done, req); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci return enc ? crypto_skcipher_encrypt(subreq) : 1558c2ecf20Sopenharmony_ci crypto_skcipher_decrypt(subreq); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic int essiv_skcipher_encrypt(struct skcipher_request *req) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci return essiv_skcipher_crypt(req, true); 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic int essiv_skcipher_decrypt(struct skcipher_request *req) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci return essiv_skcipher_crypt(req, false); 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic void essiv_aead_done(struct crypto_async_request *areq, int err) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci struct aead_request *req = areq->data; 1718c2ecf20Sopenharmony_ci struct essiv_aead_request_ctx *rctx = aead_request_ctx(req); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci if (err == -EINPROGRESS) 1748c2ecf20Sopenharmony_ci goto out; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci kfree(rctx->assoc); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ciout: 1798c2ecf20Sopenharmony_ci aead_request_complete(req, err); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic int essiv_aead_crypt(struct aead_request *req, bool enc) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1858c2ecf20Sopenharmony_ci const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); 1868c2ecf20Sopenharmony_ci struct essiv_aead_request_ctx *rctx = aead_request_ctx(req); 1878c2ecf20Sopenharmony_ci struct aead_request *subreq = &rctx->aead_req; 1888c2ecf20Sopenharmony_ci struct scatterlist *src = req->src; 1898c2ecf20Sopenharmony_ci int err; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci /* 1948c2ecf20Sopenharmony_ci * dm-crypt embeds the sector number and the IV in the AAD region, so 1958c2ecf20Sopenharmony_ci * we have to copy the converted IV into the right scatterlist before 1968c2ecf20Sopenharmony_ci * we pass it on. 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci rctx->assoc = NULL; 1998c2ecf20Sopenharmony_ci if (req->src == req->dst || !enc) { 2008c2ecf20Sopenharmony_ci scatterwalk_map_and_copy(req->iv, req->dst, 2018c2ecf20Sopenharmony_ci req->assoclen - crypto_aead_ivsize(tfm), 2028c2ecf20Sopenharmony_ci crypto_aead_ivsize(tfm), 1); 2038c2ecf20Sopenharmony_ci } else { 2048c2ecf20Sopenharmony_ci u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset; 2058c2ecf20Sopenharmony_ci int ivsize = crypto_aead_ivsize(tfm); 2068c2ecf20Sopenharmony_ci int ssize = req->assoclen - ivsize; 2078c2ecf20Sopenharmony_ci struct scatterlist *sg; 2088c2ecf20Sopenharmony_ci int nents; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci if (ssize < 0) 2118c2ecf20Sopenharmony_ci return -EINVAL; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci nents = sg_nents_for_len(req->src, ssize); 2148c2ecf20Sopenharmony_ci if (nents < 0) 2158c2ecf20Sopenharmony_ci return -EINVAL; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci memcpy(iv, req->iv, ivsize); 2188c2ecf20Sopenharmony_ci sg_init_table(rctx->sg, 4); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci if (unlikely(nents > 1)) { 2218c2ecf20Sopenharmony_ci /* 2228c2ecf20Sopenharmony_ci * This is a case that rarely occurs in practice, but 2238c2ecf20Sopenharmony_ci * for correctness, we have to deal with it nonetheless. 2248c2ecf20Sopenharmony_ci */ 2258c2ecf20Sopenharmony_ci rctx->assoc = kmalloc(ssize, GFP_ATOMIC); 2268c2ecf20Sopenharmony_ci if (!rctx->assoc) 2278c2ecf20Sopenharmony_ci return -ENOMEM; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci scatterwalk_map_and_copy(rctx->assoc, req->src, 0, 2308c2ecf20Sopenharmony_ci ssize, 0); 2318c2ecf20Sopenharmony_ci sg_set_buf(rctx->sg, rctx->assoc, ssize); 2328c2ecf20Sopenharmony_ci } else { 2338c2ecf20Sopenharmony_ci sg_set_page(rctx->sg, sg_page(req->src), ssize, 2348c2ecf20Sopenharmony_ci req->src->offset); 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci sg_set_buf(rctx->sg + 1, iv, ivsize); 2388c2ecf20Sopenharmony_ci sg = scatterwalk_ffwd(rctx->sg + 2, req->src, req->assoclen); 2398c2ecf20Sopenharmony_ci if (sg != rctx->sg + 2) 2408c2ecf20Sopenharmony_ci sg_chain(rctx->sg, 3, sg); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci src = rctx->sg; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci aead_request_set_tfm(subreq, tctx->u.aead); 2468c2ecf20Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 2478c2ecf20Sopenharmony_ci aead_request_set_callback(subreq, aead_request_flags(req), 2488c2ecf20Sopenharmony_ci essiv_aead_done, req); 2498c2ecf20Sopenharmony_ci aead_request_set_crypt(subreq, src, req->dst, req->cryptlen, req->iv); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci err = enc ? crypto_aead_encrypt(subreq) : 2528c2ecf20Sopenharmony_ci crypto_aead_decrypt(subreq); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci if (rctx->assoc && err != -EINPROGRESS && err != -EBUSY) 2558c2ecf20Sopenharmony_ci kfree(rctx->assoc); 2568c2ecf20Sopenharmony_ci return err; 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistatic int essiv_aead_encrypt(struct aead_request *req) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci return essiv_aead_crypt(req, true); 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic int essiv_aead_decrypt(struct aead_request *req) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci return essiv_aead_crypt(req, false); 2678c2ecf20Sopenharmony_ci} 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_cistatic int essiv_init_tfm(struct essiv_instance_ctx *ictx, 2708c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx) 2718c2ecf20Sopenharmony_ci{ 2728c2ecf20Sopenharmony_ci struct crypto_cipher *essiv_cipher; 2738c2ecf20Sopenharmony_ci struct crypto_shash *hash; 2748c2ecf20Sopenharmony_ci int err; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci essiv_cipher = crypto_alloc_cipher(ictx->essiv_cipher_name, 0, 0); 2778c2ecf20Sopenharmony_ci if (IS_ERR(essiv_cipher)) 2788c2ecf20Sopenharmony_ci return PTR_ERR(essiv_cipher); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci hash = crypto_alloc_shash(ictx->shash_driver_name, 0, 0); 2818c2ecf20Sopenharmony_ci if (IS_ERR(hash)) { 2828c2ecf20Sopenharmony_ci err = PTR_ERR(hash); 2838c2ecf20Sopenharmony_ci goto err_free_essiv_cipher; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci tctx->essiv_cipher = essiv_cipher; 2878c2ecf20Sopenharmony_ci tctx->hash = hash; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci return 0; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cierr_free_essiv_cipher: 2928c2ecf20Sopenharmony_ci crypto_free_cipher(essiv_cipher); 2938c2ecf20Sopenharmony_ci return err; 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_cistatic int essiv_skcipher_init_tfm(struct crypto_skcipher *tfm) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci struct skcipher_instance *inst = skcipher_alg_instance(tfm); 2998c2ecf20Sopenharmony_ci struct essiv_instance_ctx *ictx = skcipher_instance_ctx(inst); 3008c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); 3018c2ecf20Sopenharmony_ci struct crypto_skcipher *skcipher; 3028c2ecf20Sopenharmony_ci int err; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci skcipher = crypto_spawn_skcipher(&ictx->u.skcipher_spawn); 3058c2ecf20Sopenharmony_ci if (IS_ERR(skcipher)) 3068c2ecf20Sopenharmony_ci return PTR_ERR(skcipher); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) + 3098c2ecf20Sopenharmony_ci crypto_skcipher_reqsize(skcipher)); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci err = essiv_init_tfm(ictx, tctx); 3128c2ecf20Sopenharmony_ci if (err) { 3138c2ecf20Sopenharmony_ci crypto_free_skcipher(skcipher); 3148c2ecf20Sopenharmony_ci return err; 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci tctx->u.skcipher = skcipher; 3188c2ecf20Sopenharmony_ci return 0; 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic int essiv_aead_init_tfm(struct crypto_aead *tfm) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci struct aead_instance *inst = aead_alg_instance(tfm); 3248c2ecf20Sopenharmony_ci struct essiv_instance_ctx *ictx = aead_instance_ctx(inst); 3258c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); 3268c2ecf20Sopenharmony_ci struct crypto_aead *aead; 3278c2ecf20Sopenharmony_ci unsigned int subreq_size; 3288c2ecf20Sopenharmony_ci int err; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci BUILD_BUG_ON(offsetofend(struct essiv_aead_request_ctx, aead_req) != 3318c2ecf20Sopenharmony_ci sizeof(struct essiv_aead_request_ctx)); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci aead = crypto_spawn_aead(&ictx->u.aead_spawn); 3348c2ecf20Sopenharmony_ci if (IS_ERR(aead)) 3358c2ecf20Sopenharmony_ci return PTR_ERR(aead); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci subreq_size = sizeof_field(struct essiv_aead_request_ctx, aead_req) + 3388c2ecf20Sopenharmony_ci crypto_aead_reqsize(aead); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci tctx->ivoffset = offsetof(struct essiv_aead_request_ctx, aead_req) + 3418c2ecf20Sopenharmony_ci subreq_size; 3428c2ecf20Sopenharmony_ci crypto_aead_set_reqsize(tfm, tctx->ivoffset + crypto_aead_ivsize(aead)); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci err = essiv_init_tfm(ictx, tctx); 3458c2ecf20Sopenharmony_ci if (err) { 3468c2ecf20Sopenharmony_ci crypto_free_aead(aead); 3478c2ecf20Sopenharmony_ci return err; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci tctx->u.aead = aead; 3518c2ecf20Sopenharmony_ci return 0; 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_cistatic void essiv_skcipher_exit_tfm(struct crypto_skcipher *tfm) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci crypto_free_skcipher(tctx->u.skcipher); 3598c2ecf20Sopenharmony_ci crypto_free_cipher(tctx->essiv_cipher); 3608c2ecf20Sopenharmony_ci crypto_free_shash(tctx->hash); 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic void essiv_aead_exit_tfm(struct crypto_aead *tfm) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci crypto_free_aead(tctx->u.aead); 3688c2ecf20Sopenharmony_ci crypto_free_cipher(tctx->essiv_cipher); 3698c2ecf20Sopenharmony_ci crypto_free_shash(tctx->hash); 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_cistatic void essiv_skcipher_free_instance(struct skcipher_instance *inst) 3738c2ecf20Sopenharmony_ci{ 3748c2ecf20Sopenharmony_ci struct essiv_instance_ctx *ictx = skcipher_instance_ctx(inst); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci crypto_drop_skcipher(&ictx->u.skcipher_spawn); 3778c2ecf20Sopenharmony_ci kfree(inst); 3788c2ecf20Sopenharmony_ci} 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_cistatic void essiv_aead_free_instance(struct aead_instance *inst) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci struct essiv_instance_ctx *ictx = aead_instance_ctx(inst); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci crypto_drop_aead(&ictx->u.aead_spawn); 3858c2ecf20Sopenharmony_ci kfree(inst); 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_cistatic bool parse_cipher_name(char *essiv_cipher_name, const char *cra_name) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci const char *p, *q; 3918c2ecf20Sopenharmony_ci int len; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* find the last opening parens */ 3948c2ecf20Sopenharmony_ci p = strrchr(cra_name, '('); 3958c2ecf20Sopenharmony_ci if (!p++) 3968c2ecf20Sopenharmony_ci return false; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci /* find the first closing parens in the tail of the string */ 3998c2ecf20Sopenharmony_ci q = strchr(p, ')'); 4008c2ecf20Sopenharmony_ci if (!q) 4018c2ecf20Sopenharmony_ci return false; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci len = q - p; 4048c2ecf20Sopenharmony_ci if (len >= CRYPTO_MAX_ALG_NAME) 4058c2ecf20Sopenharmony_ci return false; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci memcpy(essiv_cipher_name, p, len); 4088c2ecf20Sopenharmony_ci essiv_cipher_name[len] = '\0'; 4098c2ecf20Sopenharmony_ci return true; 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_cistatic bool essiv_supported_algorithms(const char *essiv_cipher_name, 4138c2ecf20Sopenharmony_ci struct shash_alg *hash_alg, 4148c2ecf20Sopenharmony_ci int ivsize) 4158c2ecf20Sopenharmony_ci{ 4168c2ecf20Sopenharmony_ci struct crypto_alg *alg; 4178c2ecf20Sopenharmony_ci bool ret = false; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci alg = crypto_alg_mod_lookup(essiv_cipher_name, 4208c2ecf20Sopenharmony_ci CRYPTO_ALG_TYPE_CIPHER, 4218c2ecf20Sopenharmony_ci CRYPTO_ALG_TYPE_MASK); 4228c2ecf20Sopenharmony_ci if (IS_ERR(alg)) 4238c2ecf20Sopenharmony_ci return false; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci if (hash_alg->digestsize < alg->cra_cipher.cia_min_keysize || 4268c2ecf20Sopenharmony_ci hash_alg->digestsize > alg->cra_cipher.cia_max_keysize) 4278c2ecf20Sopenharmony_ci goto out; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci if (ivsize != alg->cra_blocksize) 4308c2ecf20Sopenharmony_ci goto out; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci if (crypto_shash_alg_needs_key(hash_alg)) 4338c2ecf20Sopenharmony_ci goto out; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci ret = true; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ciout: 4388c2ecf20Sopenharmony_ci crypto_mod_put(alg); 4398c2ecf20Sopenharmony_ci return ret; 4408c2ecf20Sopenharmony_ci} 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_cistatic int essiv_create(struct crypto_template *tmpl, struct rtattr **tb) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci struct crypto_attr_type *algt; 4458c2ecf20Sopenharmony_ci const char *inner_cipher_name; 4468c2ecf20Sopenharmony_ci const char *shash_name; 4478c2ecf20Sopenharmony_ci struct skcipher_instance *skcipher_inst = NULL; 4488c2ecf20Sopenharmony_ci struct aead_instance *aead_inst = NULL; 4498c2ecf20Sopenharmony_ci struct crypto_instance *inst; 4508c2ecf20Sopenharmony_ci struct crypto_alg *base, *block_base; 4518c2ecf20Sopenharmony_ci struct essiv_instance_ctx *ictx; 4528c2ecf20Sopenharmony_ci struct skcipher_alg *skcipher_alg = NULL; 4538c2ecf20Sopenharmony_ci struct aead_alg *aead_alg = NULL; 4548c2ecf20Sopenharmony_ci struct crypto_alg *_hash_alg; 4558c2ecf20Sopenharmony_ci struct shash_alg *hash_alg; 4568c2ecf20Sopenharmony_ci int ivsize; 4578c2ecf20Sopenharmony_ci u32 type; 4588c2ecf20Sopenharmony_ci u32 mask; 4598c2ecf20Sopenharmony_ci int err; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci algt = crypto_get_attr_type(tb); 4628c2ecf20Sopenharmony_ci if (IS_ERR(algt)) 4638c2ecf20Sopenharmony_ci return PTR_ERR(algt); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci inner_cipher_name = crypto_attr_alg_name(tb[1]); 4668c2ecf20Sopenharmony_ci if (IS_ERR(inner_cipher_name)) 4678c2ecf20Sopenharmony_ci return PTR_ERR(inner_cipher_name); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci shash_name = crypto_attr_alg_name(tb[2]); 4708c2ecf20Sopenharmony_ci if (IS_ERR(shash_name)) 4718c2ecf20Sopenharmony_ci return PTR_ERR(shash_name); 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci type = algt->type & algt->mask; 4748c2ecf20Sopenharmony_ci mask = crypto_algt_inherited_mask(algt); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci switch (type) { 4778c2ecf20Sopenharmony_ci case CRYPTO_ALG_TYPE_SKCIPHER: 4788c2ecf20Sopenharmony_ci skcipher_inst = kzalloc(sizeof(*skcipher_inst) + 4798c2ecf20Sopenharmony_ci sizeof(*ictx), GFP_KERNEL); 4808c2ecf20Sopenharmony_ci if (!skcipher_inst) 4818c2ecf20Sopenharmony_ci return -ENOMEM; 4828c2ecf20Sopenharmony_ci inst = skcipher_crypto_instance(skcipher_inst); 4838c2ecf20Sopenharmony_ci base = &skcipher_inst->alg.base; 4848c2ecf20Sopenharmony_ci ictx = crypto_instance_ctx(inst); 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci /* Symmetric cipher, e.g., "cbc(aes)" */ 4878c2ecf20Sopenharmony_ci err = crypto_grab_skcipher(&ictx->u.skcipher_spawn, inst, 4888c2ecf20Sopenharmony_ci inner_cipher_name, 0, mask); 4898c2ecf20Sopenharmony_ci if (err) 4908c2ecf20Sopenharmony_ci goto out_free_inst; 4918c2ecf20Sopenharmony_ci skcipher_alg = crypto_spawn_skcipher_alg(&ictx->u.skcipher_spawn); 4928c2ecf20Sopenharmony_ci block_base = &skcipher_alg->base; 4938c2ecf20Sopenharmony_ci ivsize = crypto_skcipher_alg_ivsize(skcipher_alg); 4948c2ecf20Sopenharmony_ci break; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci case CRYPTO_ALG_TYPE_AEAD: 4978c2ecf20Sopenharmony_ci aead_inst = kzalloc(sizeof(*aead_inst) + 4988c2ecf20Sopenharmony_ci sizeof(*ictx), GFP_KERNEL); 4998c2ecf20Sopenharmony_ci if (!aead_inst) 5008c2ecf20Sopenharmony_ci return -ENOMEM; 5018c2ecf20Sopenharmony_ci inst = aead_crypto_instance(aead_inst); 5028c2ecf20Sopenharmony_ci base = &aead_inst->alg.base; 5038c2ecf20Sopenharmony_ci ictx = crypto_instance_ctx(inst); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci /* AEAD cipher, e.g., "authenc(hmac(sha256),cbc(aes))" */ 5068c2ecf20Sopenharmony_ci err = crypto_grab_aead(&ictx->u.aead_spawn, inst, 5078c2ecf20Sopenharmony_ci inner_cipher_name, 0, mask); 5088c2ecf20Sopenharmony_ci if (err) 5098c2ecf20Sopenharmony_ci goto out_free_inst; 5108c2ecf20Sopenharmony_ci aead_alg = crypto_spawn_aead_alg(&ictx->u.aead_spawn); 5118c2ecf20Sopenharmony_ci block_base = &aead_alg->base; 5128c2ecf20Sopenharmony_ci if (!strstarts(block_base->cra_name, "authenc(")) { 5138c2ecf20Sopenharmony_ci pr_warn("Only authenc() type AEADs are supported by ESSIV\n"); 5148c2ecf20Sopenharmony_ci err = -EINVAL; 5158c2ecf20Sopenharmony_ci goto out_drop_skcipher; 5168c2ecf20Sopenharmony_ci } 5178c2ecf20Sopenharmony_ci ivsize = aead_alg->ivsize; 5188c2ecf20Sopenharmony_ci break; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci default: 5218c2ecf20Sopenharmony_ci return -EINVAL; 5228c2ecf20Sopenharmony_ci } 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci if (!parse_cipher_name(ictx->essiv_cipher_name, block_base->cra_name)) { 5258c2ecf20Sopenharmony_ci pr_warn("Failed to parse ESSIV cipher name from skcipher cra_name\n"); 5268c2ecf20Sopenharmony_ci err = -EINVAL; 5278c2ecf20Sopenharmony_ci goto out_drop_skcipher; 5288c2ecf20Sopenharmony_ci } 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci /* Synchronous hash, e.g., "sha256" */ 5318c2ecf20Sopenharmony_ci _hash_alg = crypto_alg_mod_lookup(shash_name, 5328c2ecf20Sopenharmony_ci CRYPTO_ALG_TYPE_SHASH, 5338c2ecf20Sopenharmony_ci CRYPTO_ALG_TYPE_MASK | mask); 5348c2ecf20Sopenharmony_ci if (IS_ERR(_hash_alg)) { 5358c2ecf20Sopenharmony_ci err = PTR_ERR(_hash_alg); 5368c2ecf20Sopenharmony_ci goto out_drop_skcipher; 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci hash_alg = __crypto_shash_alg(_hash_alg); 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci /* Check the set of algorithms */ 5418c2ecf20Sopenharmony_ci if (!essiv_supported_algorithms(ictx->essiv_cipher_name, hash_alg, 5428c2ecf20Sopenharmony_ci ivsize)) { 5438c2ecf20Sopenharmony_ci pr_warn("Unsupported essiv instantiation: essiv(%s,%s)\n", 5448c2ecf20Sopenharmony_ci block_base->cra_name, hash_alg->base.cra_name); 5458c2ecf20Sopenharmony_ci err = -EINVAL; 5468c2ecf20Sopenharmony_ci goto out_free_hash; 5478c2ecf20Sopenharmony_ci } 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci /* record the driver name so we can instantiate this exact algo later */ 5508c2ecf20Sopenharmony_ci strlcpy(ictx->shash_driver_name, hash_alg->base.cra_driver_name, 5518c2ecf20Sopenharmony_ci CRYPTO_MAX_ALG_NAME); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci /* Instance fields */ 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci err = -ENAMETOOLONG; 5568c2ecf20Sopenharmony_ci if (snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, 5578c2ecf20Sopenharmony_ci "essiv(%s,%s)", block_base->cra_name, 5588c2ecf20Sopenharmony_ci hash_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) 5598c2ecf20Sopenharmony_ci goto out_free_hash; 5608c2ecf20Sopenharmony_ci if (snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, 5618c2ecf20Sopenharmony_ci "essiv(%s,%s)", block_base->cra_driver_name, 5628c2ecf20Sopenharmony_ci hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 5638c2ecf20Sopenharmony_ci goto out_free_hash; 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci /* 5668c2ecf20Sopenharmony_ci * hash_alg wasn't gotten via crypto_grab*(), so we need to inherit its 5678c2ecf20Sopenharmony_ci * flags manually. 5688c2ecf20Sopenharmony_ci */ 5698c2ecf20Sopenharmony_ci base->cra_flags |= (hash_alg->base.cra_flags & 5708c2ecf20Sopenharmony_ci CRYPTO_ALG_INHERITED_FLAGS); 5718c2ecf20Sopenharmony_ci base->cra_blocksize = block_base->cra_blocksize; 5728c2ecf20Sopenharmony_ci base->cra_ctxsize = sizeof(struct essiv_tfm_ctx); 5738c2ecf20Sopenharmony_ci base->cra_alignmask = block_base->cra_alignmask; 5748c2ecf20Sopenharmony_ci base->cra_priority = block_base->cra_priority; 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci if (type == CRYPTO_ALG_TYPE_SKCIPHER) { 5778c2ecf20Sopenharmony_ci skcipher_inst->alg.setkey = essiv_skcipher_setkey; 5788c2ecf20Sopenharmony_ci skcipher_inst->alg.encrypt = essiv_skcipher_encrypt; 5798c2ecf20Sopenharmony_ci skcipher_inst->alg.decrypt = essiv_skcipher_decrypt; 5808c2ecf20Sopenharmony_ci skcipher_inst->alg.init = essiv_skcipher_init_tfm; 5818c2ecf20Sopenharmony_ci skcipher_inst->alg.exit = essiv_skcipher_exit_tfm; 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci skcipher_inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(skcipher_alg); 5848c2ecf20Sopenharmony_ci skcipher_inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(skcipher_alg); 5858c2ecf20Sopenharmony_ci skcipher_inst->alg.ivsize = ivsize; 5868c2ecf20Sopenharmony_ci skcipher_inst->alg.chunksize = crypto_skcipher_alg_chunksize(skcipher_alg); 5878c2ecf20Sopenharmony_ci skcipher_inst->alg.walksize = crypto_skcipher_alg_walksize(skcipher_alg); 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci skcipher_inst->free = essiv_skcipher_free_instance; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci err = skcipher_register_instance(tmpl, skcipher_inst); 5928c2ecf20Sopenharmony_ci } else { 5938c2ecf20Sopenharmony_ci aead_inst->alg.setkey = essiv_aead_setkey; 5948c2ecf20Sopenharmony_ci aead_inst->alg.setauthsize = essiv_aead_setauthsize; 5958c2ecf20Sopenharmony_ci aead_inst->alg.encrypt = essiv_aead_encrypt; 5968c2ecf20Sopenharmony_ci aead_inst->alg.decrypt = essiv_aead_decrypt; 5978c2ecf20Sopenharmony_ci aead_inst->alg.init = essiv_aead_init_tfm; 5988c2ecf20Sopenharmony_ci aead_inst->alg.exit = essiv_aead_exit_tfm; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci aead_inst->alg.ivsize = ivsize; 6018c2ecf20Sopenharmony_ci aead_inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(aead_alg); 6028c2ecf20Sopenharmony_ci aead_inst->alg.chunksize = crypto_aead_alg_chunksize(aead_alg); 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci aead_inst->free = essiv_aead_free_instance; 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci err = aead_register_instance(tmpl, aead_inst); 6078c2ecf20Sopenharmony_ci } 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci if (err) 6108c2ecf20Sopenharmony_ci goto out_free_hash; 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci crypto_mod_put(_hash_alg); 6138c2ecf20Sopenharmony_ci return 0; 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ciout_free_hash: 6168c2ecf20Sopenharmony_ci crypto_mod_put(_hash_alg); 6178c2ecf20Sopenharmony_ciout_drop_skcipher: 6188c2ecf20Sopenharmony_ci if (type == CRYPTO_ALG_TYPE_SKCIPHER) 6198c2ecf20Sopenharmony_ci crypto_drop_skcipher(&ictx->u.skcipher_spawn); 6208c2ecf20Sopenharmony_ci else 6218c2ecf20Sopenharmony_ci crypto_drop_aead(&ictx->u.aead_spawn); 6228c2ecf20Sopenharmony_ciout_free_inst: 6238c2ecf20Sopenharmony_ci kfree(skcipher_inst); 6248c2ecf20Sopenharmony_ci kfree(aead_inst); 6258c2ecf20Sopenharmony_ci return err; 6268c2ecf20Sopenharmony_ci} 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci/* essiv(cipher_name, shash_name) */ 6298c2ecf20Sopenharmony_cistatic struct crypto_template essiv_tmpl = { 6308c2ecf20Sopenharmony_ci .name = "essiv", 6318c2ecf20Sopenharmony_ci .create = essiv_create, 6328c2ecf20Sopenharmony_ci .module = THIS_MODULE, 6338c2ecf20Sopenharmony_ci}; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_cistatic int __init essiv_module_init(void) 6368c2ecf20Sopenharmony_ci{ 6378c2ecf20Sopenharmony_ci return crypto_register_template(&essiv_tmpl); 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic void __exit essiv_module_exit(void) 6418c2ecf20Sopenharmony_ci{ 6428c2ecf20Sopenharmony_ci crypto_unregister_template(&essiv_tmpl); 6438c2ecf20Sopenharmony_ci} 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_cisubsys_initcall(essiv_module_init); 6468c2ecf20Sopenharmony_cimodule_exit(essiv_module_exit); 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ESSIV skcipher/aead wrapper for block encryption"); 6498c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 6508c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("essiv"); 651