1d9b45418SCorentin Labbe // SPDX-License-Identifier: GPL-2.0 2d9b45418SCorentin Labbe /* 3d9b45418SCorentin Labbe * sun8i-ss-hash.c - hardware cryptographic offloader for 4d9b45418SCorentin Labbe * Allwinner A80/A83T SoC 5d9b45418SCorentin Labbe * 6d9b45418SCorentin Labbe * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com> 7d9b45418SCorentin Labbe * 8d9b45418SCorentin Labbe * This file add support for MD5 and SHA1/SHA224/SHA256. 9d9b45418SCorentin Labbe * 10*39db3f15SJonathan Corbet * You could find the datasheet in Documentation/arch/arm/sunxi.rst 11d9b45418SCorentin Labbe */ 12b169b376SCorentin Labbe #include <linux/bottom_half.h> 13d9b45418SCorentin Labbe #include <linux/dma-mapping.h> 14d9b45418SCorentin Labbe #include <linux/pm_runtime.h> 15d9b45418SCorentin Labbe #include <linux/scatterlist.h> 16d9b45418SCorentin Labbe #include <crypto/internal/hash.h> 17801b7d57SCorentin Labbe #include <crypto/hmac.h> 18c35e523aSCorentin Labbe #include <crypto/scatterwalk.h> 19a24d22b2SEric Biggers #include <crypto/sha1.h> 20a24d22b2SEric Biggers #include <crypto/sha2.h> 21d9b45418SCorentin Labbe #include <crypto/md5.h> 22d9b45418SCorentin Labbe #include "sun8i-ss.h" 23d9b45418SCorentin Labbe 24801b7d57SCorentin Labbe static int sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx *tfmctx, const u8 *key, 25801b7d57SCorentin Labbe unsigned int keylen) 26801b7d57SCorentin Labbe { 27801b7d57SCorentin Labbe struct crypto_shash *xtfm; 28801b7d57SCorentin Labbe struct shash_desc *sdesc; 29801b7d57SCorentin Labbe size_t len; 30801b7d57SCorentin Labbe int ret = 0; 31801b7d57SCorentin Labbe 32801b7d57SCorentin Labbe xtfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_NEED_FALLBACK); 337e8df1fcSPeng Wu if (IS_ERR(xtfm)) 347e8df1fcSPeng Wu return PTR_ERR(xtfm); 35801b7d57SCorentin Labbe 36801b7d57SCorentin Labbe len = sizeof(*sdesc) + crypto_shash_descsize(xtfm); 37801b7d57SCorentin Labbe sdesc = kmalloc(len, GFP_KERNEL); 38801b7d57SCorentin Labbe if (!sdesc) { 39801b7d57SCorentin Labbe ret = -ENOMEM; 40801b7d57SCorentin Labbe goto err_hashkey_sdesc; 41801b7d57SCorentin Labbe } 42801b7d57SCorentin Labbe sdesc->tfm = xtfm; 43801b7d57SCorentin Labbe 44801b7d57SCorentin Labbe ret = crypto_shash_init(sdesc); 45801b7d57SCorentin Labbe if (ret) { 46801b7d57SCorentin Labbe dev_err(tfmctx->ss->dev, "shash init error ret=%d\n", ret); 47801b7d57SCorentin Labbe goto err_hashkey; 48801b7d57SCorentin Labbe } 49801b7d57SCorentin Labbe ret = crypto_shash_finup(sdesc, key, keylen, tfmctx->key); 50801b7d57SCorentin Labbe if (ret) 51801b7d57SCorentin Labbe dev_err(tfmctx->ss->dev, "shash finup error\n"); 52801b7d57SCorentin Labbe err_hashkey: 53801b7d57SCorentin Labbe kfree(sdesc); 54801b7d57SCorentin Labbe err_hashkey_sdesc: 55801b7d57SCorentin Labbe crypto_free_shash(xtfm); 56801b7d57SCorentin Labbe return ret; 57801b7d57SCorentin Labbe } 58801b7d57SCorentin Labbe 59801b7d57SCorentin Labbe int sun8i_ss_hmac_setkey(struct crypto_ahash *ahash, const u8 *key, 60801b7d57SCorentin Labbe unsigned int keylen) 61801b7d57SCorentin Labbe { 62801b7d57SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(ahash); 63801b7d57SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(ahash->base.__crt_alg); 64801b7d57SCorentin Labbe struct sun8i_ss_alg_template *algt; 65801b7d57SCorentin Labbe int digestsize, i; 66801b7d57SCorentin Labbe int bs = crypto_ahash_blocksize(ahash); 67801b7d57SCorentin Labbe int ret; 68801b7d57SCorentin Labbe 69801b7d57SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 70801b7d57SCorentin Labbe digestsize = algt->alg.hash.halg.digestsize; 71801b7d57SCorentin Labbe 72801b7d57SCorentin Labbe if (keylen > bs) { 73801b7d57SCorentin Labbe ret = sun8i_ss_hashkey(tfmctx, key, keylen); 74801b7d57SCorentin Labbe if (ret) 75801b7d57SCorentin Labbe return ret; 76801b7d57SCorentin Labbe tfmctx->keylen = digestsize; 77801b7d57SCorentin Labbe } else { 78801b7d57SCorentin Labbe tfmctx->keylen = keylen; 79801b7d57SCorentin Labbe memcpy(tfmctx->key, key, keylen); 80801b7d57SCorentin Labbe } 81801b7d57SCorentin Labbe 8239a76cf1SHerbert Xu tfmctx->ipad = kzalloc(bs, GFP_KERNEL); 83801b7d57SCorentin Labbe if (!tfmctx->ipad) 84801b7d57SCorentin Labbe return -ENOMEM; 8539a76cf1SHerbert Xu tfmctx->opad = kzalloc(bs, GFP_KERNEL); 86801b7d57SCorentin Labbe if (!tfmctx->opad) { 87801b7d57SCorentin Labbe ret = -ENOMEM; 88801b7d57SCorentin Labbe goto err_opad; 89801b7d57SCorentin Labbe } 90801b7d57SCorentin Labbe 91801b7d57SCorentin Labbe memset(tfmctx->key + tfmctx->keylen, 0, bs - tfmctx->keylen); 92801b7d57SCorentin Labbe memcpy(tfmctx->ipad, tfmctx->key, tfmctx->keylen); 93801b7d57SCorentin Labbe memcpy(tfmctx->opad, tfmctx->key, tfmctx->keylen); 94801b7d57SCorentin Labbe for (i = 0; i < bs; i++) { 95801b7d57SCorentin Labbe tfmctx->ipad[i] ^= HMAC_IPAD_VALUE; 96801b7d57SCorentin Labbe tfmctx->opad[i] ^= HMAC_OPAD_VALUE; 97801b7d57SCorentin Labbe } 98801b7d57SCorentin Labbe 99801b7d57SCorentin Labbe ret = crypto_ahash_setkey(tfmctx->fallback_tfm, key, keylen); 100801b7d57SCorentin Labbe if (!ret) 101801b7d57SCorentin Labbe return 0; 102801b7d57SCorentin Labbe 103801b7d57SCorentin Labbe memzero_explicit(tfmctx->key, keylen); 104801b7d57SCorentin Labbe kfree_sensitive(tfmctx->opad); 105801b7d57SCorentin Labbe err_opad: 106801b7d57SCorentin Labbe kfree_sensitive(tfmctx->ipad); 107801b7d57SCorentin Labbe return ret; 108801b7d57SCorentin Labbe } 109801b7d57SCorentin Labbe 110d9b45418SCorentin Labbe int sun8i_ss_hash_crainit(struct crypto_tfm *tfm) 111d9b45418SCorentin Labbe { 112d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *op = crypto_tfm_ctx(tfm); 113d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); 114d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 115d9b45418SCorentin Labbe int err; 116d9b45418SCorentin Labbe 117d9b45418SCorentin Labbe memset(op, 0, sizeof(struct sun8i_ss_hash_tfm_ctx)); 118d9b45418SCorentin Labbe 119d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 120d9b45418SCorentin Labbe op->ss = algt->ss; 121d9b45418SCorentin Labbe 122d9b45418SCorentin Labbe op->enginectx.op.do_one_request = sun8i_ss_hash_run; 123d9b45418SCorentin Labbe op->enginectx.op.prepare_request = NULL; 124d9b45418SCorentin Labbe op->enginectx.op.unprepare_request = NULL; 125d9b45418SCorentin Labbe 126d9b45418SCorentin Labbe /* FALLBACK */ 127d9b45418SCorentin Labbe op->fallback_tfm = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0, 128d9b45418SCorentin Labbe CRYPTO_ALG_NEED_FALLBACK); 129d9b45418SCorentin Labbe if (IS_ERR(op->fallback_tfm)) { 130d9b45418SCorentin Labbe dev_err(algt->ss->dev, "Fallback driver could no be loaded\n"); 131d9b45418SCorentin Labbe return PTR_ERR(op->fallback_tfm); 132d9b45418SCorentin Labbe } 133d9b45418SCorentin Labbe 134d9b45418SCorentin Labbe if (algt->alg.hash.halg.statesize < crypto_ahash_statesize(op->fallback_tfm)) 135d9b45418SCorentin Labbe algt->alg.hash.halg.statesize = crypto_ahash_statesize(op->fallback_tfm); 136d9b45418SCorentin Labbe 137d9b45418SCorentin Labbe crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 138d9b45418SCorentin Labbe sizeof(struct sun8i_ss_hash_reqctx) + 139d9b45418SCorentin Labbe crypto_ahash_reqsize(op->fallback_tfm)); 140d9b45418SCorentin Labbe 141f95f61d0SCorentin Labbe memcpy(algt->fbname, crypto_tfm_alg_driver_name(&op->fallback_tfm->base), CRYPTO_MAX_ALG_NAME); 142f95f61d0SCorentin Labbe 143d9b45418SCorentin Labbe err = pm_runtime_get_sync(op->ss->dev); 144d9b45418SCorentin Labbe if (err < 0) 145d9b45418SCorentin Labbe goto error_pm; 146d9b45418SCorentin Labbe return 0; 147d9b45418SCorentin Labbe error_pm: 148d9b45418SCorentin Labbe pm_runtime_put_noidle(op->ss->dev); 149d9b45418SCorentin Labbe crypto_free_ahash(op->fallback_tfm); 150d9b45418SCorentin Labbe return err; 151d9b45418SCorentin Labbe } 152d9b45418SCorentin Labbe 153d9b45418SCorentin Labbe void sun8i_ss_hash_craexit(struct crypto_tfm *tfm) 154d9b45418SCorentin Labbe { 155d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_tfm_ctx(tfm); 156d9b45418SCorentin Labbe 157801b7d57SCorentin Labbe kfree_sensitive(tfmctx->ipad); 158801b7d57SCorentin Labbe kfree_sensitive(tfmctx->opad); 159801b7d57SCorentin Labbe 160d9b45418SCorentin Labbe crypto_free_ahash(tfmctx->fallback_tfm); 161d9b45418SCorentin Labbe pm_runtime_put_sync_suspend(tfmctx->ss->dev); 162d9b45418SCorentin Labbe } 163d9b45418SCorentin Labbe 164d9b45418SCorentin Labbe int sun8i_ss_hash_init(struct ahash_request *areq) 165d9b45418SCorentin Labbe { 166d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 167d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 168d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 169d9b45418SCorentin Labbe 170d9b45418SCorentin Labbe memset(rctx, 0, sizeof(struct sun8i_ss_hash_reqctx)); 171d9b45418SCorentin Labbe 172d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 173d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 174d9b45418SCorentin Labbe 175d9b45418SCorentin Labbe return crypto_ahash_init(&rctx->fallback_req); 176d9b45418SCorentin Labbe } 177d9b45418SCorentin Labbe 178d9b45418SCorentin Labbe int sun8i_ss_hash_export(struct ahash_request *areq, void *out) 179d9b45418SCorentin Labbe { 180d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 181d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 182d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 183d9b45418SCorentin Labbe 184d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 185d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 186d9b45418SCorentin Labbe 187d9b45418SCorentin Labbe return crypto_ahash_export(&rctx->fallback_req, out); 188d9b45418SCorentin Labbe } 189d9b45418SCorentin Labbe 190d9b45418SCorentin Labbe int sun8i_ss_hash_import(struct ahash_request *areq, const void *in) 191d9b45418SCorentin Labbe { 192d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 193d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 194d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 195d9b45418SCorentin Labbe 196d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 197d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; 198d9b45418SCorentin Labbe 199d9b45418SCorentin Labbe return crypto_ahash_import(&rctx->fallback_req, in); 200d9b45418SCorentin Labbe } 201d9b45418SCorentin Labbe 202d9b45418SCorentin Labbe int sun8i_ss_hash_final(struct ahash_request *areq) 203d9b45418SCorentin Labbe { 204d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 205d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 206d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 207d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 208d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 209d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 210d9b45418SCorentin Labbe #endif 211d9b45418SCorentin Labbe 212d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 213d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & 214d9b45418SCorentin Labbe CRYPTO_TFM_REQ_MAY_SLEEP; 215d9b45418SCorentin Labbe rctx->fallback_req.result = areq->result; 216d9b45418SCorentin Labbe 217d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 218d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 219d9b45418SCorentin Labbe algt->stat_fb++; 220d9b45418SCorentin Labbe #endif 221d9b45418SCorentin Labbe 222d9b45418SCorentin Labbe return crypto_ahash_final(&rctx->fallback_req); 223d9b45418SCorentin Labbe } 224d9b45418SCorentin Labbe 225d9b45418SCorentin Labbe int sun8i_ss_hash_update(struct ahash_request *areq) 226d9b45418SCorentin Labbe { 227d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 228d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 229d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 230d9b45418SCorentin Labbe 231d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 232d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & 233d9b45418SCorentin Labbe CRYPTO_TFM_REQ_MAY_SLEEP; 234d9b45418SCorentin Labbe rctx->fallback_req.nbytes = areq->nbytes; 235d9b45418SCorentin Labbe rctx->fallback_req.src = areq->src; 236d9b45418SCorentin Labbe 237d9b45418SCorentin Labbe return crypto_ahash_update(&rctx->fallback_req); 238d9b45418SCorentin Labbe } 239d9b45418SCorentin Labbe 240d9b45418SCorentin Labbe int sun8i_ss_hash_finup(struct ahash_request *areq) 241d9b45418SCorentin Labbe { 242d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 243d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 244d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 245d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 246d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 247d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 248d9b45418SCorentin Labbe #endif 249d9b45418SCorentin Labbe 250d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 251d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & 252d9b45418SCorentin Labbe CRYPTO_TFM_REQ_MAY_SLEEP; 253d9b45418SCorentin Labbe 254d9b45418SCorentin Labbe rctx->fallback_req.nbytes = areq->nbytes; 255d9b45418SCorentin Labbe rctx->fallback_req.src = areq->src; 256d9b45418SCorentin Labbe rctx->fallback_req.result = areq->result; 257d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 258d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 259d9b45418SCorentin Labbe algt->stat_fb++; 260d9b45418SCorentin Labbe #endif 261d9b45418SCorentin Labbe 262d9b45418SCorentin Labbe return crypto_ahash_finup(&rctx->fallback_req); 263d9b45418SCorentin Labbe } 264d9b45418SCorentin Labbe 265d9b45418SCorentin Labbe static int sun8i_ss_hash_digest_fb(struct ahash_request *areq) 266d9b45418SCorentin Labbe { 267d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 268d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 269d9b45418SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 270d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 271d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 272d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 273d9b45418SCorentin Labbe #endif 274d9b45418SCorentin Labbe 275d9b45418SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); 276d9b45418SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags & 277d9b45418SCorentin Labbe CRYPTO_TFM_REQ_MAY_SLEEP; 278d9b45418SCorentin Labbe 279d9b45418SCorentin Labbe rctx->fallback_req.nbytes = areq->nbytes; 280d9b45418SCorentin Labbe rctx->fallback_req.src = areq->src; 281d9b45418SCorentin Labbe rctx->fallback_req.result = areq->result; 282d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 283d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 284d9b45418SCorentin Labbe algt->stat_fb++; 285d9b45418SCorentin Labbe #endif 286d9b45418SCorentin Labbe 287d9b45418SCorentin Labbe return crypto_ahash_digest(&rctx->fallback_req); 288d9b45418SCorentin Labbe } 289d9b45418SCorentin Labbe 290d9b45418SCorentin Labbe static int sun8i_ss_run_hash_task(struct sun8i_ss_dev *ss, 291d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx, 292d9b45418SCorentin Labbe const char *name) 293d9b45418SCorentin Labbe { 294d9b45418SCorentin Labbe int flow = rctx->flow; 295d9b45418SCorentin Labbe u32 v = SS_START; 296d9b45418SCorentin Labbe int i; 297d9b45418SCorentin Labbe 298d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 299d9b45418SCorentin Labbe ss->flows[flow].stat_req++; 300d9b45418SCorentin Labbe #endif 301d9b45418SCorentin Labbe 302d9b45418SCorentin Labbe /* choose between stream0/stream1 */ 303d9b45418SCorentin Labbe if (flow) 304d9b45418SCorentin Labbe v |= SS_FLOW1; 305d9b45418SCorentin Labbe else 306d9b45418SCorentin Labbe v |= SS_FLOW0; 307d9b45418SCorentin Labbe 308d9b45418SCorentin Labbe v |= rctx->method; 309d9b45418SCorentin Labbe 310d9b45418SCorentin Labbe for (i = 0; i < MAX_SG; i++) { 311d9b45418SCorentin Labbe if (!rctx->t_dst[i].addr) 312d9b45418SCorentin Labbe break; 313d9b45418SCorentin Labbe 314d9b45418SCorentin Labbe mutex_lock(&ss->mlock); 315d9b45418SCorentin Labbe if (i > 0) { 316d9b45418SCorentin Labbe v |= BIT(17); 317d9b45418SCorentin Labbe writel(rctx->t_dst[i - 1].addr, ss->base + SS_KEY_ADR_REG); 318d9b45418SCorentin Labbe writel(rctx->t_dst[i - 1].addr, ss->base + SS_IV_ADR_REG); 319d9b45418SCorentin Labbe } 320d9b45418SCorentin Labbe 321d9b45418SCorentin Labbe dev_dbg(ss->dev, 322d9b45418SCorentin Labbe "Processing SG %d on flow %d %s ctl=%x %d to %d method=%x src=%x dst=%x\n", 323d9b45418SCorentin Labbe i, flow, name, v, 324d9b45418SCorentin Labbe rctx->t_src[i].len, rctx->t_dst[i].len, 325d9b45418SCorentin Labbe rctx->method, rctx->t_src[i].addr, rctx->t_dst[i].addr); 326d9b45418SCorentin Labbe 327d9b45418SCorentin Labbe writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG); 328d9b45418SCorentin Labbe writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG); 329d9b45418SCorentin Labbe writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG); 330d9b45418SCorentin Labbe writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG); 331d9b45418SCorentin Labbe 332d9b45418SCorentin Labbe reinit_completion(&ss->flows[flow].complete); 333d9b45418SCorentin Labbe ss->flows[flow].status = 0; 334d9b45418SCorentin Labbe wmb(); 335d9b45418SCorentin Labbe 336d9b45418SCorentin Labbe writel(v, ss->base + SS_CTL_REG); 337d9b45418SCorentin Labbe mutex_unlock(&ss->mlock); 338d9b45418SCorentin Labbe wait_for_completion_interruptible_timeout(&ss->flows[flow].complete, 339d9b45418SCorentin Labbe msecs_to_jiffies(2000)); 340d9b45418SCorentin Labbe if (ss->flows[flow].status == 0) { 341d9b45418SCorentin Labbe dev_err(ss->dev, "DMA timeout for %s\n", name); 342d9b45418SCorentin Labbe return -EFAULT; 343d9b45418SCorentin Labbe } 344d9b45418SCorentin Labbe } 345d9b45418SCorentin Labbe 346d9b45418SCorentin Labbe return 0; 347d9b45418SCorentin Labbe } 348d9b45418SCorentin Labbe 349d9b45418SCorentin Labbe static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq) 350d9b45418SCorentin Labbe { 351f95f61d0SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 352f95f61d0SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 353f95f61d0SCorentin Labbe struct sun8i_ss_alg_template *algt; 354d9b45418SCorentin Labbe struct scatterlist *sg; 355d9b45418SCorentin Labbe 356f95f61d0SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 357f95f61d0SCorentin Labbe 358f95f61d0SCorentin Labbe if (areq->nbytes == 0) { 359f95f61d0SCorentin Labbe algt->stat_fb_len++; 360d9b45418SCorentin Labbe return true; 361f95f61d0SCorentin Labbe } 362f95f61d0SCorentin Labbe 363f95f61d0SCorentin Labbe if (areq->nbytes >= MAX_PAD_SIZE - 64) { 364f95f61d0SCorentin Labbe algt->stat_fb_len++; 365c35e523aSCorentin Labbe return true; 366f95f61d0SCorentin Labbe } 367c35e523aSCorentin Labbe 368d9b45418SCorentin Labbe /* we need to reserve one SG for the padding one */ 369f95f61d0SCorentin Labbe if (sg_nents(areq->src) > MAX_SG - 1) { 370f95f61d0SCorentin Labbe algt->stat_fb_sgnum++; 371d9b45418SCorentin Labbe return true; 372f95f61d0SCorentin Labbe } 373f95f61d0SCorentin Labbe 374d9b45418SCorentin Labbe sg = areq->src; 375d9b45418SCorentin Labbe while (sg) { 376d9b45418SCorentin Labbe /* SS can operate hash only on full block size 377d9b45418SCorentin Labbe * since SS support only MD5,sha1,sha224 and sha256, blocksize 378d9b45418SCorentin Labbe * is always 64 379d9b45418SCorentin Labbe */ 380c35e523aSCorentin Labbe /* Only the last block could be bounced to the pad buffer */ 381f95f61d0SCorentin Labbe if (sg->length % 64 && sg_next(sg)) { 382f95f61d0SCorentin Labbe algt->stat_fb_sglen++; 383c35e523aSCorentin Labbe return true; 384f95f61d0SCorentin Labbe } 385f95f61d0SCorentin Labbe if (!IS_ALIGNED(sg->offset, sizeof(u32))) { 386f95f61d0SCorentin Labbe algt->stat_fb_align++; 387c35e523aSCorentin Labbe return true; 388f95f61d0SCorentin Labbe } 389f95f61d0SCorentin Labbe if (sg->length % 4) { 390f95f61d0SCorentin Labbe algt->stat_fb_sglen++; 391d9b45418SCorentin Labbe return true; 392f95f61d0SCorentin Labbe } 393d9b45418SCorentin Labbe sg = sg_next(sg); 394d9b45418SCorentin Labbe } 395d9b45418SCorentin Labbe return false; 396d9b45418SCorentin Labbe } 397d9b45418SCorentin Labbe 398d9b45418SCorentin Labbe int sun8i_ss_hash_digest(struct ahash_request *areq) 399d9b45418SCorentin Labbe { 400d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 401d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 402d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 403d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 404d9b45418SCorentin Labbe struct sun8i_ss_dev *ss; 405d9b45418SCorentin Labbe struct crypto_engine *engine; 40646e2fcbcSCorentin Labbe int e; 407d9b45418SCorentin Labbe 408d9b45418SCorentin Labbe if (sun8i_ss_hash_need_fallback(areq)) 409d9b45418SCorentin Labbe return sun8i_ss_hash_digest_fb(areq); 410d9b45418SCorentin Labbe 411d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 412d9b45418SCorentin Labbe ss = algt->ss; 413d9b45418SCorentin Labbe 414d9b45418SCorentin Labbe e = sun8i_ss_get_engine_number(ss); 415d9b45418SCorentin Labbe rctx->flow = e; 416d9b45418SCorentin Labbe engine = ss->flows[e].engine; 417d9b45418SCorentin Labbe 418d9b45418SCorentin Labbe return crypto_transfer_hash_request_to_engine(engine, areq); 419d9b45418SCorentin Labbe } 420d9b45418SCorentin Labbe 421e76ee4dbSCorentin Labbe static u64 hash_pad(__le32 *buf, unsigned int bufsize, u64 padi, u64 byte_count, bool le, int bs) 422e76ee4dbSCorentin Labbe { 423e76ee4dbSCorentin Labbe u64 fill, min_fill, j, k; 424e76ee4dbSCorentin Labbe __be64 *bebits; 425e76ee4dbSCorentin Labbe __le64 *lebits; 426e76ee4dbSCorentin Labbe 427e76ee4dbSCorentin Labbe j = padi; 428e76ee4dbSCorentin Labbe buf[j++] = cpu_to_le32(0x80); 429e76ee4dbSCorentin Labbe 430e76ee4dbSCorentin Labbe if (bs == 64) { 431e76ee4dbSCorentin Labbe fill = 64 - (byte_count % 64); 432e76ee4dbSCorentin Labbe min_fill = 2 * sizeof(u32) + sizeof(u32); 433e76ee4dbSCorentin Labbe } else { 434e76ee4dbSCorentin Labbe fill = 128 - (byte_count % 128); 435e76ee4dbSCorentin Labbe min_fill = 4 * sizeof(u32) + sizeof(u32); 436e76ee4dbSCorentin Labbe } 437e76ee4dbSCorentin Labbe 438e76ee4dbSCorentin Labbe if (fill < min_fill) 439e76ee4dbSCorentin Labbe fill += bs; 440e76ee4dbSCorentin Labbe 441e76ee4dbSCorentin Labbe k = j; 442e76ee4dbSCorentin Labbe j += (fill - min_fill) / sizeof(u32); 443e76ee4dbSCorentin Labbe if (j * 4 > bufsize) { 444e76ee4dbSCorentin Labbe pr_err("%s OVERFLOW %llu\n", __func__, j); 445e76ee4dbSCorentin Labbe return 0; 446e76ee4dbSCorentin Labbe } 447e76ee4dbSCorentin Labbe for (; k < j; k++) 448e76ee4dbSCorentin Labbe buf[k] = 0; 449e76ee4dbSCorentin Labbe 450e76ee4dbSCorentin Labbe if (le) { 451e76ee4dbSCorentin Labbe /* MD5 */ 452e76ee4dbSCorentin Labbe lebits = (__le64 *)&buf[j]; 453e76ee4dbSCorentin Labbe *lebits = cpu_to_le64(byte_count << 3); 454e76ee4dbSCorentin Labbe j += 2; 455e76ee4dbSCorentin Labbe } else { 456e76ee4dbSCorentin Labbe if (bs == 64) { 457e76ee4dbSCorentin Labbe /* sha1 sha224 sha256 */ 458e76ee4dbSCorentin Labbe bebits = (__be64 *)&buf[j]; 459e76ee4dbSCorentin Labbe *bebits = cpu_to_be64(byte_count << 3); 460e76ee4dbSCorentin Labbe j += 2; 461e76ee4dbSCorentin Labbe } else { 462e76ee4dbSCorentin Labbe /* sha384 sha512*/ 463e76ee4dbSCorentin Labbe bebits = (__be64 *)&buf[j]; 464e76ee4dbSCorentin Labbe *bebits = cpu_to_be64(byte_count >> 61); 465e76ee4dbSCorentin Labbe j += 2; 466e76ee4dbSCorentin Labbe bebits = (__be64 *)&buf[j]; 467e76ee4dbSCorentin Labbe *bebits = cpu_to_be64(byte_count << 3); 468e76ee4dbSCorentin Labbe j += 2; 469e76ee4dbSCorentin Labbe } 470e76ee4dbSCorentin Labbe } 471e76ee4dbSCorentin Labbe if (j * 4 > bufsize) { 472e76ee4dbSCorentin Labbe pr_err("%s OVERFLOW %llu\n", __func__, j); 473e76ee4dbSCorentin Labbe return 0; 474e76ee4dbSCorentin Labbe } 475e76ee4dbSCorentin Labbe 476e76ee4dbSCorentin Labbe return j; 477e76ee4dbSCorentin Labbe } 478e76ee4dbSCorentin Labbe 479d9b45418SCorentin Labbe /* sun8i_ss_hash_run - run an ahash request 480d9b45418SCorentin Labbe * Send the data of the request to the SS along with an extra SG with padding 481d9b45418SCorentin Labbe */ 482d9b45418SCorentin Labbe int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) 483d9b45418SCorentin Labbe { 484d9b45418SCorentin Labbe struct ahash_request *areq = container_of(breq, struct ahash_request, base); 485d9b45418SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 486801b7d57SCorentin Labbe struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); 487d9b45418SCorentin Labbe struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); 488d9b45418SCorentin Labbe struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq); 489d9b45418SCorentin Labbe struct sun8i_ss_alg_template *algt; 490d9b45418SCorentin Labbe struct sun8i_ss_dev *ss; 491d9b45418SCorentin Labbe struct scatterlist *sg; 492801b7d57SCorentin Labbe int bs = crypto_ahash_blocksize(tfm); 493d9b45418SCorentin Labbe int nr_sgs, err, digestsize; 494d9b45418SCorentin Labbe unsigned int len; 495e76ee4dbSCorentin Labbe u64 byte_count; 496d9b45418SCorentin Labbe void *pad, *result; 497db0c62bcSCorentin Labbe int j, i, k, todo; 498801b7d57SCorentin Labbe dma_addr_t addr_res, addr_pad, addr_xpad; 499d9b45418SCorentin Labbe __le32 *bf; 500801b7d57SCorentin Labbe /* HMAC step: 501801b7d57SCorentin Labbe * 0: normal hashing 502801b7d57SCorentin Labbe * 1: IPAD 503801b7d57SCorentin Labbe * 2: OPAD 504801b7d57SCorentin Labbe */ 505801b7d57SCorentin Labbe int hmac = 0; 506d9b45418SCorentin Labbe 507d9b45418SCorentin Labbe algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash); 508d9b45418SCorentin Labbe ss = algt->ss; 509d9b45418SCorentin Labbe 510d9b45418SCorentin Labbe digestsize = algt->alg.hash.halg.digestsize; 511d9b45418SCorentin Labbe if (digestsize == SHA224_DIGEST_SIZE) 512d9b45418SCorentin Labbe digestsize = SHA256_DIGEST_SIZE; 513d9b45418SCorentin Labbe 5148eec4563SCorentin Labbe result = ss->flows[rctx->flow].result; 5158eec4563SCorentin Labbe pad = ss->flows[rctx->flow].pad; 516d9b45418SCorentin Labbe bf = (__le32 *)pad; 517d9b45418SCorentin Labbe 518d9b45418SCorentin Labbe for (i = 0; i < MAX_SG; i++) { 519d9b45418SCorentin Labbe rctx->t_dst[i].addr = 0; 520d9b45418SCorentin Labbe rctx->t_dst[i].len = 0; 521d9b45418SCorentin Labbe } 522d9b45418SCorentin Labbe 523d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 524d9b45418SCorentin Labbe algt->stat_req++; 525d9b45418SCorentin Labbe #endif 526d9b45418SCorentin Labbe 527d9b45418SCorentin Labbe rctx->method = ss->variant->alg_hash[algt->ss_algo_id]; 528d9b45418SCorentin Labbe 529d9b45418SCorentin Labbe nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); 530d9b45418SCorentin Labbe if (nr_sgs <= 0 || nr_sgs > MAX_SG) { 531d9b45418SCorentin Labbe dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs); 532d9b45418SCorentin Labbe err = -EINVAL; 533d9b45418SCorentin Labbe goto theend; 534d9b45418SCorentin Labbe } 535d9b45418SCorentin Labbe 536d9b45418SCorentin Labbe addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE); 537d9b45418SCorentin Labbe if (dma_mapping_error(ss->dev, addr_res)) { 538d9b45418SCorentin Labbe dev_err(ss->dev, "DMA map dest\n"); 539d9b45418SCorentin Labbe err = -EINVAL; 540801b7d57SCorentin Labbe goto err_dma_result; 541d9b45418SCorentin Labbe } 542d9b45418SCorentin Labbe 543c35e523aSCorentin Labbe j = 0; 544d9b45418SCorentin Labbe len = areq->nbytes; 545c149e476SCorentin Labbe sg = areq->src; 546c149e476SCorentin Labbe i = 0; 547c149e476SCorentin Labbe while (len > 0 && sg) { 548c149e476SCorentin Labbe if (sg_dma_len(sg) == 0) { 549c149e476SCorentin Labbe sg = sg_next(sg); 550c149e476SCorentin Labbe continue; 551c149e476SCorentin Labbe } 552d9b45418SCorentin Labbe todo = min(len, sg_dma_len(sg)); 553c35e523aSCorentin Labbe /* only the last SG could be with a size not modulo64 */ 554c35e523aSCorentin Labbe if (todo % 64 == 0) { 555c35e523aSCorentin Labbe rctx->t_src[i].addr = sg_dma_address(sg); 556d9b45418SCorentin Labbe rctx->t_src[i].len = todo / 4; 557d9b45418SCorentin Labbe rctx->t_dst[i].addr = addr_res; 558d9b45418SCorentin Labbe rctx->t_dst[i].len = digestsize / 4; 559c35e523aSCorentin Labbe len -= todo; 560c35e523aSCorentin Labbe } else { 561c35e523aSCorentin Labbe scatterwalk_map_and_copy(bf, sg, 0, todo, 0); 562c35e523aSCorentin Labbe j += todo / 4; 563c35e523aSCorentin Labbe len -= todo; 564c35e523aSCorentin Labbe } 565c149e476SCorentin Labbe sg = sg_next(sg); 566c149e476SCorentin Labbe i++; 567d9b45418SCorentin Labbe } 568d9b45418SCorentin Labbe if (len > 0) { 569d9b45418SCorentin Labbe dev_err(ss->dev, "remaining len %d\n", len); 570d9b45418SCorentin Labbe err = -EINVAL; 571d9b45418SCorentin Labbe goto theend; 572d9b45418SCorentin Labbe } 573d9b45418SCorentin Labbe 574c35e523aSCorentin Labbe if (j > 0) 575c35e523aSCorentin Labbe i--; 576c35e523aSCorentin Labbe 577801b7d57SCorentin Labbe retry: 578d9b45418SCorentin Labbe byte_count = areq->nbytes; 579801b7d57SCorentin Labbe if (tfmctx->keylen && hmac == 0) { 580801b7d57SCorentin Labbe hmac = 1; 581801b7d57SCorentin Labbe /* shift all SG one slot up, to free slot 0 for IPAD */ 582801b7d57SCorentin Labbe for (k = 6; k >= 0; k--) { 583801b7d57SCorentin Labbe rctx->t_src[k + 1].addr = rctx->t_src[k].addr; 584801b7d57SCorentin Labbe rctx->t_src[k + 1].len = rctx->t_src[k].len; 585801b7d57SCorentin Labbe rctx->t_dst[k + 1].addr = rctx->t_dst[k].addr; 586801b7d57SCorentin Labbe rctx->t_dst[k + 1].len = rctx->t_dst[k].len; 587801b7d57SCorentin Labbe } 588801b7d57SCorentin Labbe addr_xpad = dma_map_single(ss->dev, tfmctx->ipad, bs, DMA_TO_DEVICE); 5896cb3f9b2SDan Carpenter err = dma_mapping_error(ss->dev, addr_xpad); 5906cb3f9b2SDan Carpenter if (err) { 591801b7d57SCorentin Labbe dev_err(ss->dev, "Fail to create DMA mapping of ipad\n"); 592801b7d57SCorentin Labbe goto err_dma_xpad; 593801b7d57SCorentin Labbe } 594801b7d57SCorentin Labbe rctx->t_src[0].addr = addr_xpad; 595801b7d57SCorentin Labbe rctx->t_src[0].len = bs / 4; 596801b7d57SCorentin Labbe rctx->t_dst[0].addr = addr_res; 597801b7d57SCorentin Labbe rctx->t_dst[0].len = digestsize / 4; 598801b7d57SCorentin Labbe i++; 599801b7d57SCorentin Labbe byte_count = areq->nbytes + bs; 600801b7d57SCorentin Labbe } 601801b7d57SCorentin Labbe if (tfmctx->keylen && hmac == 2) { 602801b7d57SCorentin Labbe for (i = 0; i < MAX_SG; i++) { 603801b7d57SCorentin Labbe rctx->t_src[i].addr = 0; 604801b7d57SCorentin Labbe rctx->t_src[i].len = 0; 605801b7d57SCorentin Labbe rctx->t_dst[i].addr = 0; 606801b7d57SCorentin Labbe rctx->t_dst[i].len = 0; 607801b7d57SCorentin Labbe } 608801b7d57SCorentin Labbe 609801b7d57SCorentin Labbe addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE); 610801b7d57SCorentin Labbe if (dma_mapping_error(ss->dev, addr_res)) { 611801b7d57SCorentin Labbe dev_err(ss->dev, "Fail to create DMA mapping of result\n"); 612801b7d57SCorentin Labbe err = -EINVAL; 613801b7d57SCorentin Labbe goto err_dma_result; 614801b7d57SCorentin Labbe } 615801b7d57SCorentin Labbe addr_xpad = dma_map_single(ss->dev, tfmctx->opad, bs, DMA_TO_DEVICE); 6166cb3f9b2SDan Carpenter err = dma_mapping_error(ss->dev, addr_xpad); 6176cb3f9b2SDan Carpenter if (err) { 618801b7d57SCorentin Labbe dev_err(ss->dev, "Fail to create DMA mapping of opad\n"); 619801b7d57SCorentin Labbe goto err_dma_xpad; 620801b7d57SCorentin Labbe } 621801b7d57SCorentin Labbe rctx->t_src[0].addr = addr_xpad; 622801b7d57SCorentin Labbe rctx->t_src[0].len = bs / 4; 623801b7d57SCorentin Labbe 624801b7d57SCorentin Labbe memcpy(bf, result, digestsize); 625801b7d57SCorentin Labbe j = digestsize / 4; 626801b7d57SCorentin Labbe i = 1; 627801b7d57SCorentin Labbe byte_count = digestsize + bs; 628801b7d57SCorentin Labbe 629801b7d57SCorentin Labbe rctx->t_dst[0].addr = addr_res; 630801b7d57SCorentin Labbe rctx->t_dst[0].len = digestsize / 4; 631801b7d57SCorentin Labbe } 632801b7d57SCorentin Labbe 633d9b45418SCorentin Labbe switch (algt->ss_algo_id) { 634d9b45418SCorentin Labbe case SS_ID_HASH_MD5: 635e76ee4dbSCorentin Labbe j = hash_pad(bf, 4096, j, byte_count, true, bs); 636d9b45418SCorentin Labbe break; 637d9b45418SCorentin Labbe case SS_ID_HASH_SHA1: 638d9b45418SCorentin Labbe case SS_ID_HASH_SHA224: 639d9b45418SCorentin Labbe case SS_ID_HASH_SHA256: 640e76ee4dbSCorentin Labbe j = hash_pad(bf, 4096, j, byte_count, false, bs); 641d9b45418SCorentin Labbe break; 642d9b45418SCorentin Labbe } 643e76ee4dbSCorentin Labbe if (!j) { 644e76ee4dbSCorentin Labbe err = -EINVAL; 645e76ee4dbSCorentin Labbe goto theend; 646e76ee4dbSCorentin Labbe } 647d9b45418SCorentin Labbe 648d9b45418SCorentin Labbe addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE); 649d9b45418SCorentin Labbe if (dma_mapping_error(ss->dev, addr_pad)) { 650d9b45418SCorentin Labbe dev_err(ss->dev, "DMA error on padding SG\n"); 651d9b45418SCorentin Labbe err = -EINVAL; 652801b7d57SCorentin Labbe goto err_dma_pad; 653d9b45418SCorentin Labbe } 654d86e3f37SCorentin Labbe rctx->t_src[i].addr = addr_pad; 655d86e3f37SCorentin Labbe rctx->t_src[i].len = j; 656d86e3f37SCorentin Labbe rctx->t_dst[i].addr = addr_res; 657d86e3f37SCorentin Labbe rctx->t_dst[i].len = digestsize / 4; 658d9b45418SCorentin Labbe 659d9b45418SCorentin Labbe err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm)); 660d9b45418SCorentin Labbe 661801b7d57SCorentin Labbe /* 662801b7d57SCorentin Labbe * mini helper for checking dma map/unmap 663801b7d57SCorentin Labbe * flow start for hmac = 0 (and HMAC = 1) 664801b7d57SCorentin Labbe * HMAC = 0 665801b7d57SCorentin Labbe * MAP src 666801b7d57SCorentin Labbe * MAP res 667801b7d57SCorentin Labbe * 668801b7d57SCorentin Labbe * retry: 669801b7d57SCorentin Labbe * if hmac then hmac = 1 670801b7d57SCorentin Labbe * MAP xpad (ipad) 671801b7d57SCorentin Labbe * if hmac == 2 672801b7d57SCorentin Labbe * MAP res 673801b7d57SCorentin Labbe * MAP xpad (opad) 674801b7d57SCorentin Labbe * MAP pad 675801b7d57SCorentin Labbe * ACTION! 676801b7d57SCorentin Labbe * UNMAP pad 677801b7d57SCorentin Labbe * if hmac 678801b7d57SCorentin Labbe * UNMAP xpad 679801b7d57SCorentin Labbe * UNMAP res 680801b7d57SCorentin Labbe * if hmac < 2 681801b7d57SCorentin Labbe * UNMAP SRC 682801b7d57SCorentin Labbe * 683801b7d57SCorentin Labbe * if hmac = 1 then hmac = 2 goto retry 684801b7d57SCorentin Labbe */ 685801b7d57SCorentin Labbe 686d9b45418SCorentin Labbe dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE); 687801b7d57SCorentin Labbe 688801b7d57SCorentin Labbe err_dma_pad: 689801b7d57SCorentin Labbe if (hmac > 0) 690801b7d57SCorentin Labbe dma_unmap_single(ss->dev, addr_xpad, bs, DMA_TO_DEVICE); 691801b7d57SCorentin Labbe err_dma_xpad: 692801b7d57SCorentin Labbe dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE); 693801b7d57SCorentin Labbe err_dma_result: 694801b7d57SCorentin Labbe if (hmac < 2) 695884b93c5SXiang Chen dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src), 696884b93c5SXiang Chen DMA_TO_DEVICE); 697801b7d57SCorentin Labbe if (hmac == 1 && !err) { 698801b7d57SCorentin Labbe hmac = 2; 699801b7d57SCorentin Labbe goto retry; 700801b7d57SCorentin Labbe } 701d9b45418SCorentin Labbe 702801b7d57SCorentin Labbe if (!err) 703d9b45418SCorentin Labbe memcpy(areq->result, result, algt->alg.hash.halg.digestsize); 704d9b45418SCorentin Labbe theend: 705b169b376SCorentin Labbe local_bh_disable(); 706d9b45418SCorentin Labbe crypto_finalize_hash_request(engine, breq, err); 707b169b376SCorentin Labbe local_bh_enable(); 708d9b45418SCorentin Labbe return 0; 709d9b45418SCorentin Labbe } 710