brintos

brintos / linux-shallow public Read only

0
0
Text · 17.8 KiB · f2dd667 Raw
645 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * sun4i-ss-cipher.c - hardware cryptographic accelerator for Allwinner A20 SoC4 *5 * Copyright (C) 2013-2015 Corentin LABBE <clabbe.montjoie@gmail.com>6 *7 * This file add support for AES cipher with 128,192,256 bits8 * keysize in CBC and ECB mode.9 * Add support also for DES and 3DES in CBC and ECB mode.10 *11 * You could find the datasheet in Documentation/arch/arm/sunxi.rst12 */13#include "sun4i-ss.h"14 15static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)16{17	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);18	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);19	struct sun4i_ss_ctx *ss = op->ss;20	unsigned int ivsize = crypto_skcipher_ivsize(tfm);21	struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);22	u32 mode = ctx->mode;23	/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */24	u32 rx_cnt = SS_RX_DEFAULT;25	u32 tx_cnt = 0;26	u32 spaces;27	u32 v;28	int err = 0;29	unsigned int i;30	unsigned int ileft = areq->cryptlen;31	unsigned int oleft = areq->cryptlen;32	unsigned int todo;33	unsigned long pi = 0, po = 0; /* progress for in and out */34	bool miter_err;35	struct sg_mapping_iter mi, mo;36	unsigned int oi, oo; /* offset for in and out */37	unsigned long flags;38	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);39	struct sun4i_ss_alg_template *algt;40 41	if (!areq->cryptlen)42		return 0;43 44	if (!areq->src || !areq->dst) {45		dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n");46		return -EINVAL;47	}48 49	if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {50		scatterwalk_map_and_copy(ctx->backup_iv, areq->src,51					 areq->cryptlen - ivsize, ivsize, 0);52	}53 54	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {55		algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);56		algt->stat_opti++;57		algt->stat_bytes += areq->cryptlen;58	}59 60	spin_lock_irqsave(&ss->slock, flags);61 62	for (i = 0; i < op->keylen / 4; i++)63		writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1);64 65	if (areq->iv) {66		for (i = 0; i < 4 && i < ivsize / 4; i++) {67			v = *(u32 *)(areq->iv + i * 4);68			writesl(ss->base + SS_IV0 + i * 4, &v, 1);69		}70	}71	writel(mode, ss->base + SS_CTL);72 73 74	ileft = areq->cryptlen / 4;75	oleft = areq->cryptlen / 4;76	oi = 0;77	oo = 0;78	do {79		if (ileft) {80			sg_miter_start(&mi, areq->src, sg_nents(areq->src),81					SG_MITER_FROM_SG | SG_MITER_ATOMIC);82			if (pi)83				sg_miter_skip(&mi, pi);84			miter_err = sg_miter_next(&mi);85			if (!miter_err || !mi.addr) {86				dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");87				err = -EINVAL;88				goto release_ss;89			}90			todo = min(rx_cnt, ileft);91			todo = min_t(size_t, todo, (mi.length - oi) / 4);92			if (todo) {93				ileft -= todo;94				writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);95				oi += todo * 4;96			}97			if (oi == mi.length) {98				pi += mi.length;99				oi = 0;100			}101			sg_miter_stop(&mi);102		}103 104		spaces = readl(ss->base + SS_FCSR);105		rx_cnt = SS_RXFIFO_SPACES(spaces);106		tx_cnt = SS_TXFIFO_SPACES(spaces);107 108		sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),109			       SG_MITER_TO_SG | SG_MITER_ATOMIC);110		if (po)111			sg_miter_skip(&mo, po);112		miter_err = sg_miter_next(&mo);113		if (!miter_err || !mo.addr) {114			dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");115			err = -EINVAL;116			goto release_ss;117		}118		todo = min(tx_cnt, oleft);119		todo = min_t(size_t, todo, (mo.length - oo) / 4);120		if (todo) {121			oleft -= todo;122			readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);123			oo += todo * 4;124		}125		if (oo == mo.length) {126			oo = 0;127			po += mo.length;128		}129		sg_miter_stop(&mo);130	} while (oleft);131 132	if (areq->iv) {133		if (mode & SS_DECRYPTION) {134			memcpy(areq->iv, ctx->backup_iv, ivsize);135			memzero_explicit(ctx->backup_iv, ivsize);136		} else {137			scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,138						 ivsize, 0);139		}140	}141 142release_ss:143	writel(0, ss->base + SS_CTL);144	spin_unlock_irqrestore(&ss->slock, flags);145	return err;146}147 148static int noinline_for_stack sun4i_ss_cipher_poll_fallback(struct skcipher_request *areq)149{150	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);151	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);152	struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);153	int err;154	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);155	struct sun4i_ss_alg_template *algt;156 157	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {158		algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);159		algt->stat_fb++;160	}161 162	skcipher_request_set_tfm(&ctx->fallback_req, op->fallback_tfm);163	skcipher_request_set_callback(&ctx->fallback_req, areq->base.flags,164				      areq->base.complete, areq->base.data);165	skcipher_request_set_crypt(&ctx->fallback_req, areq->src, areq->dst,166				   areq->cryptlen, areq->iv);167	if (ctx->mode & SS_DECRYPTION)168		err = crypto_skcipher_decrypt(&ctx->fallback_req);169	else170		err = crypto_skcipher_encrypt(&ctx->fallback_req);171 172	return err;173}174 175/* Generic function that support SG with size not multiple of 4 */176static int sun4i_ss_cipher_poll(struct skcipher_request *areq)177{178	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);179	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);180	struct sun4i_ss_ctx *ss = op->ss;181	int no_chunk = 1;182	struct scatterlist *in_sg = areq->src;183	struct scatterlist *out_sg = areq->dst;184	unsigned int ivsize = crypto_skcipher_ivsize(tfm);185	struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);186	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);187	struct sun4i_ss_alg_template *algt;188	u32 mode = ctx->mode;189	/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */190	u32 rx_cnt = SS_RX_DEFAULT;191	u32 tx_cnt = 0;192	u32 v;193	u32 spaces;194	int err = 0;195	unsigned int i;196	unsigned int ileft = areq->cryptlen;197	unsigned int oleft = areq->cryptlen;198	unsigned int todo;199	struct sg_mapping_iter mi, mo;200	unsigned long pi = 0, po = 0; /* progress for in and out */201	bool miter_err;202	unsigned int oi, oo;	/* offset for in and out */203	unsigned int ob = 0;	/* offset in buf */204	unsigned int obo = 0;	/* offset in bufo*/205	unsigned int obl = 0;	/* length of data in bufo */206	unsigned long flags;207	bool need_fallback = false;208 209	if (!areq->cryptlen)210		return 0;211 212	if (!areq->src || !areq->dst) {213		dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n");214		return -EINVAL;215	}216 217	algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);218	if (areq->cryptlen % algt->alg.crypto.base.cra_blocksize)219		need_fallback = true;220 221	/*222	 * if we have only SGs with size multiple of 4,223	 * we can use the SS optimized function224	 */225	while (in_sg && no_chunk == 1) {226		if ((in_sg->length | in_sg->offset) & 3u)227			no_chunk = 0;228		in_sg = sg_next(in_sg);229	}230	while (out_sg && no_chunk == 1) {231		if ((out_sg->length | out_sg->offset) & 3u)232			no_chunk = 0;233		out_sg = sg_next(out_sg);234	}235 236	if (no_chunk == 1 && !need_fallback)237		return sun4i_ss_opti_poll(areq);238 239	if (need_fallback)240		return sun4i_ss_cipher_poll_fallback(areq);241 242	if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {243		scatterwalk_map_and_copy(ctx->backup_iv, areq->src,244					 areq->cryptlen - ivsize, ivsize, 0);245	}246 247	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {248		algt->stat_req++;249		algt->stat_bytes += areq->cryptlen;250	}251 252	spin_lock_irqsave(&ss->slock, flags);253 254	for (i = 0; i < op->keylen / 4; i++)255		writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1);256 257	if (areq->iv) {258		for (i = 0; i < 4 && i < ivsize / 4; i++) {259			v = *(u32 *)(areq->iv + i * 4);260			writesl(ss->base + SS_IV0 + i * 4, &v, 1);261		}262	}263	writel(mode, ss->base + SS_CTL);264 265	ileft = areq->cryptlen;266	oleft = areq->cryptlen;267	oi = 0;268	oo = 0;269 270	while (oleft) {271		if (ileft) {272			sg_miter_start(&mi, areq->src, sg_nents(areq->src),273				       SG_MITER_FROM_SG | SG_MITER_ATOMIC);274			if (pi)275				sg_miter_skip(&mi, pi);276			miter_err = sg_miter_next(&mi);277			if (!miter_err || !mi.addr) {278				dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");279				err = -EINVAL;280				goto release_ss;281			}282			/*283			 * todo is the number of consecutive 4byte word that we284			 * can read from current SG285			 */286			todo = min(rx_cnt, ileft / 4);287			todo = min_t(size_t, todo, (mi.length - oi) / 4);288			if (todo && !ob) {289				writesl(ss->base + SS_RXFIFO, mi.addr + oi,290					todo);291				ileft -= todo * 4;292				oi += todo * 4;293			} else {294				/*295				 * not enough consecutive bytes, so we need to296				 * linearize in buf. todo is in bytes297				 * After that copy, if we have a multiple of 4298				 * we need to be able to write all buf in one299				 * pass, so it is why we min() with rx_cnt300				 */301				todo = min(rx_cnt * 4 - ob, ileft);302				todo = min_t(size_t, todo, mi.length - oi);303				memcpy(ss->buf + ob, mi.addr + oi, todo);304				ileft -= todo;305				oi += todo;306				ob += todo;307				if (!(ob % 4)) {308					writesl(ss->base + SS_RXFIFO, ss->buf,309						ob / 4);310					ob = 0;311				}312			}313			if (oi == mi.length) {314				pi += mi.length;315				oi = 0;316			}317			sg_miter_stop(&mi);318		}319 320		spaces = readl(ss->base + SS_FCSR);321		rx_cnt = SS_RXFIFO_SPACES(spaces);322		tx_cnt = SS_TXFIFO_SPACES(spaces);323 324		if (!tx_cnt)325			continue;326		sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),327			       SG_MITER_TO_SG | SG_MITER_ATOMIC);328		if (po)329			sg_miter_skip(&mo, po);330		miter_err = sg_miter_next(&mo);331		if (!miter_err || !mo.addr) {332			dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");333			err = -EINVAL;334			goto release_ss;335		}336		/* todo in 4bytes word */337		todo = min(tx_cnt, oleft / 4);338		todo = min_t(size_t, todo, (mo.length - oo) / 4);339 340		if (todo) {341			readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);342			oleft -= todo * 4;343			oo += todo * 4;344			if (oo == mo.length) {345				po += mo.length;346				oo = 0;347			}348		} else {349			/*350			 * read obl bytes in bufo, we read at maximum for351			 * emptying the device352			 */353			readsl(ss->base + SS_TXFIFO, ss->bufo, tx_cnt);354			obl = tx_cnt * 4;355			obo = 0;356			do {357				/*358				 * how many bytes we can copy ?359				 * no more than remaining SG size360				 * no more than remaining buffer361				 * no need to test against oleft362				 */363				todo = min_t(size_t,364					     mo.length - oo, obl - obo);365				memcpy(mo.addr + oo, ss->bufo + obo, todo);366				oleft -= todo;367				obo += todo;368				oo += todo;369				if (oo == mo.length) {370					po += mo.length;371					sg_miter_next(&mo);372					oo = 0;373				}374			} while (obo < obl);375			/* bufo must be fully used here */376		}377		sg_miter_stop(&mo);378	}379	if (areq->iv) {380		if (mode & SS_DECRYPTION) {381			memcpy(areq->iv, ctx->backup_iv, ivsize);382			memzero_explicit(ctx->backup_iv, ivsize);383		} else {384			scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,385						 ivsize, 0);386		}387	}388 389release_ss:390	writel(0, ss->base + SS_CTL);391	spin_unlock_irqrestore(&ss->slock, flags);392 393	return err;394}395 396/* CBC AES */397int sun4i_ss_cbc_aes_encrypt(struct skcipher_request *areq)398{399	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);400	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);401	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);402 403	rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |404		op->keymode;405	return sun4i_ss_cipher_poll(areq);406}407 408int sun4i_ss_cbc_aes_decrypt(struct skcipher_request *areq)409{410	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);411	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);412	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);413 414	rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_DECRYPTION |415		op->keymode;416	return sun4i_ss_cipher_poll(areq);417}418 419/* ECB AES */420int sun4i_ss_ecb_aes_encrypt(struct skcipher_request *areq)421{422	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);423	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);424	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);425 426	rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |427		op->keymode;428	return sun4i_ss_cipher_poll(areq);429}430 431int sun4i_ss_ecb_aes_decrypt(struct skcipher_request *areq)432{433	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);434	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);435	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);436 437	rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_DECRYPTION |438		op->keymode;439	return sun4i_ss_cipher_poll(areq);440}441 442/* CBC DES */443int sun4i_ss_cbc_des_encrypt(struct skcipher_request *areq)444{445	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);446	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);447	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);448 449	rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |450		op->keymode;451	return sun4i_ss_cipher_poll(areq);452}453 454int sun4i_ss_cbc_des_decrypt(struct skcipher_request *areq)455{456	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);457	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);458	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);459 460	rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_DECRYPTION |461		op->keymode;462	return sun4i_ss_cipher_poll(areq);463}464 465/* ECB DES */466int sun4i_ss_ecb_des_encrypt(struct skcipher_request *areq)467{468	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);469	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);470	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);471 472	rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |473		op->keymode;474	return sun4i_ss_cipher_poll(areq);475}476 477int sun4i_ss_ecb_des_decrypt(struct skcipher_request *areq)478{479	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);480	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);481	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);482 483	rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_DECRYPTION |484		op->keymode;485	return sun4i_ss_cipher_poll(areq);486}487 488/* CBC 3DES */489int sun4i_ss_cbc_des3_encrypt(struct skcipher_request *areq)490{491	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);492	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);493	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);494 495	rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |496		op->keymode;497	return sun4i_ss_cipher_poll(areq);498}499 500int sun4i_ss_cbc_des3_decrypt(struct skcipher_request *areq)501{502	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);503	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);504	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);505 506	rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_DECRYPTION |507		op->keymode;508	return sun4i_ss_cipher_poll(areq);509}510 511/* ECB 3DES */512int sun4i_ss_ecb_des3_encrypt(struct skcipher_request *areq)513{514	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);515	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);516	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);517 518	rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |519		op->keymode;520	return sun4i_ss_cipher_poll(areq);521}522 523int sun4i_ss_ecb_des3_decrypt(struct skcipher_request *areq)524{525	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);526	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);527	struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);528 529	rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_DECRYPTION |530		op->keymode;531	return sun4i_ss_cipher_poll(areq);532}533 534int sun4i_ss_cipher_init(struct crypto_tfm *tfm)535{536	struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm);537	struct sun4i_ss_alg_template *algt;538	const char *name = crypto_tfm_alg_name(tfm);539	int err;540 541	memset(op, 0, sizeof(struct sun4i_tfm_ctx));542 543	algt = container_of(tfm->__crt_alg, struct sun4i_ss_alg_template,544			    alg.crypto.base);545	op->ss = algt->ss;546 547	op->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);548	if (IS_ERR(op->fallback_tfm)) {549		dev_err(op->ss->dev, "ERROR: Cannot allocate fallback for %s %ld\n",550			name, PTR_ERR(op->fallback_tfm));551		return PTR_ERR(op->fallback_tfm);552	}553 554	crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),555				    sizeof(struct sun4i_cipher_req_ctx) +556				    crypto_skcipher_reqsize(op->fallback_tfm));557 558	err = pm_runtime_resume_and_get(op->ss->dev);559	if (err < 0)560		goto error_pm;561 562	return 0;563error_pm:564	crypto_free_skcipher(op->fallback_tfm);565	return err;566}567 568void sun4i_ss_cipher_exit(struct crypto_tfm *tfm)569{570	struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm);571 572	crypto_free_skcipher(op->fallback_tfm);573	pm_runtime_put(op->ss->dev);574}575 576/* check and set the AES key, prepare the mode to be used */577int sun4i_ss_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,578			unsigned int keylen)579{580	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);581	struct sun4i_ss_ctx *ss = op->ss;582 583	switch (keylen) {584	case 128 / 8:585		op->keymode = SS_AES_128BITS;586		break;587	case 192 / 8:588		op->keymode = SS_AES_192BITS;589		break;590	case 256 / 8:591		op->keymode = SS_AES_256BITS;592		break;593	default:594		dev_dbg(ss->dev, "ERROR: Invalid keylen %u\n", keylen);595		return -EINVAL;596	}597	op->keylen = keylen;598	memcpy(op->key, key, keylen);599 600	crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);601	crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);602 603	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);604}605 606/* check and set the DES key, prepare the mode to be used */607int sun4i_ss_des_setkey(struct crypto_skcipher *tfm, const u8 *key,608			unsigned int keylen)609{610	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);611	int err;612 613	err = verify_skcipher_des_key(tfm, key);614	if (err)615		return err;616 617	op->keylen = keylen;618	memcpy(op->key, key, keylen);619 620	crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);621	crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);622 623	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);624}625 626/* check and set the 3DES key, prepare the mode to be used */627int sun4i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,628			 unsigned int keylen)629{630	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);631	int err;632 633	err = verify_skcipher_des3_key(tfm, key);634	if (err)635		return err;636 637	op->keylen = keylen;638	memcpy(op->key, key, keylen);639 640	crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);641	crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);642 643	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);644}645