12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568 |
- /*
- * Shared descriptors for aead, ablkcipher algorithms
- *
- * Copyright 2016 NXP
- */
- #include "compat.h"
- #include "desc_constr.h"
- #include "caamalg_desc.h"
- /*
- * For aead functions, read payload and write payload,
- * both of which are specified in req->src and req->dst
- */
- static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
- {
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
- KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
- }
- /* Set DK bit in class 1 operation if shared */
- static inline void append_dec_op1(u32 *desc, u32 type)
- {
- u32 *jump_cmd, *uncond_jump_cmd;
- /* DK bit is valid only for AES */
- if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
- append_operation(desc, type | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT);
- return;
- }
- jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
- append_operation(desc, type | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT);
- uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
- set_jump_tgt_here(desc, jump_cmd);
- append_operation(desc, type | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_AAI_DK);
- set_jump_tgt_here(desc, uncond_jump_cmd);
- }
- /**
- * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
- * (non-protocol) with no (null) encryption.
- * @desc: pointer to buffer used for descriptor construction
- * @adata: pointer to authentication transform definitions.
- * A split key is required for SEC Era < 6; the size of the split key
- * is specified in this case. Valid algorithm values - one of
- * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
- * with OP_ALG_AAI_HMAC_PRECOMP.
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @era: SEC Era
- */
- void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
- unsigned int icvsize, int era)
- {
- u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (era < 6) {
- if (adata->key_inline)
- append_key_as_imm(desc, adata->key_virt,
- adata->keylen_pad, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT |
- KEY_ENC);
- else
- append_key(desc, adata->key_dma, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
- } else {
- append_proto_dkp(desc, adata);
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- /* assoclen + cryptlen = seqinlen */
- append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* Prepare to read and write cryptlen + assoclen bytes */
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- /*
- * MOVE_LEN opcode is not available in all SEC HW revisions,
- * thus need to do some magic, i.e. self-patch the descriptor
- * buffer.
- */
- read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
- MOVE_DEST_MATH3 |
- (0x6 << MOVE_LEN_SHIFT));
- write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
- MOVE_DEST_DESCBUF |
- MOVE_WAITCOMP |
- (0x8 << MOVE_LEN_SHIFT));
- /* Class 2 operation */
- append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Read and write cryptlen bytes */
- aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
- set_move_tgt_here(desc, read_move_cmd);
- set_move_tgt_here(desc, write_move_cmd);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
- MOVE_AUX_LS);
- /* Write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "aead null enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
- /**
- * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
- * (non-protocol) with no (null) decryption.
- * @desc: pointer to buffer used for descriptor construction
- * @adata: pointer to authentication transform definitions.
- * A split key is required for SEC Era < 6; the size of the split key
- * is specified in this case. Valid algorithm values - one of
- * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
- * with OP_ALG_AAI_HMAC_PRECOMP.
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @era: SEC Era
- */
- void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
- unsigned int icvsize, int era)
- {
- u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (era < 6) {
- if (adata->key_inline)
- append_key_as_imm(desc, adata->key_virt,
- adata->keylen_pad, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT |
- KEY_ENC);
- else
- append_key(desc, adata->key_dma, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
- } else {
- append_proto_dkp(desc, adata);
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Class 2 operation */
- append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_ICV_ON);
- /* assoclen + cryptlen = seqoutlen */
- append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* Prepare to read and write cryptlen + assoclen bytes */
- append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
- /*
- * MOVE_LEN opcode is not available in all SEC HW revisions,
- * thus need to do some magic, i.e. self-patch the descriptor
- * buffer.
- */
- read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
- MOVE_DEST_MATH2 |
- (0x6 << MOVE_LEN_SHIFT));
- write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
- MOVE_DEST_DESCBUF |
- MOVE_WAITCOMP |
- (0x8 << MOVE_LEN_SHIFT));
- /* Read and write cryptlen bytes */
- aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
- /*
- * Insert a NOP here, since we need at least 4 instructions between
- * code patching the descriptor buffer and the location being patched.
- */
- jump_cmd = append_jump(desc, JUMP_TEST_ALL);
- set_jump_tgt_here(desc, jump_cmd);
- set_move_tgt_here(desc, read_move_cmd);
- set_move_tgt_here(desc, write_move_cmd);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
- MOVE_AUX_LS);
- append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
- /* Load ICV */
- append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
- FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "aead null dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
- static void init_sh_desc_key_aead(u32 * const desc,
- struct alginfo * const cdata,
- struct alginfo * const adata,
- const bool is_rfc3686, u32 *nonce, int era)
- {
- u32 *key_jump_cmd;
- unsigned int enckeylen = cdata->keylen;
- /* Note: Context registers are saved. */
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /*
- * RFC3686 specific:
- * | key = {AUTH_KEY, ENC_KEY, NONCE}
- * | enckeylen = encryption key size + nonce size
- */
- if (is_rfc3686)
- enckeylen -= CTR_RFC3686_NONCE_SIZE;
- if (era < 6) {
- if (adata->key_inline)
- append_key_as_imm(desc, adata->key_virt,
- adata->keylen_pad, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT |
- KEY_ENC);
- else
- append_key(desc, adata->key_dma, adata->keylen,
- CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
- } else {
- append_proto_dkp(desc, adata);
- }
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, enckeylen,
- enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- /* Load Counter into CONTEXT1 reg */
- if (is_rfc3686) {
- append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
- LDST_CLASS_IND_CCB |
- LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
- append_move(desc,
- MOVE_SRC_OUTFIFO |
- MOVE_DEST_CLASS1CTX |
- (16 << MOVE_OFFSET_SHIFT) |
- (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- }
- /**
- * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
- * @adata: pointer to authentication transform definitions.
- * A split key is required for SEC Era < 6; the size of the split key
- * is specified in this case. Valid algorithm values - one of
- * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
- * with OP_ALG_AAI_HMAC_PRECOMP.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @nonce: pointer to rfc3686 nonce
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- * @is_qi: true when called from caam/qi
- * @era: SEC Era
- */
- void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
- struct alginfo *adata, unsigned int ivsize,
- unsigned int icvsize, const bool is_rfc3686,
- u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
- int era)
- {
- /* Note: Context registers are saved. */
- init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
- /* Class 2 operation */
- append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (ctx1_iv_off << LDST_OFFSET_SHIFT));
- }
- /* Read and write assoclen bytes */
- if (is_qi || era < 3) {
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- } else {
- append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
- }
- /* Skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* read assoc before reading payload */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
- FIFOLDST_VLF);
- /* Load Counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Read and write cryptlen bytes */
- append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
- /* Write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR, "aead enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
- /**
- * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
- * @adata: pointer to authentication transform definitions.
- * A split key is required for SEC Era < 6; the size of the split key
- * is specified in this case. Valid algorithm values - one of
- * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
- * with OP_ALG_AAI_HMAC_PRECOMP.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @nonce: pointer to rfc3686 nonce
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- * @is_qi: true when called from caam/qi
- * @era: SEC Era
- */
- void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
- struct alginfo *adata, unsigned int ivsize,
- unsigned int icvsize, const bool geniv,
- const bool is_rfc3686, u32 *nonce,
- const u32 ctx1_iv_off, const bool is_qi, int era)
- {
- /* Note: Context registers are saved. */
- init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
- /* Class 2 operation */
- append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_ICV_ON);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- if (!geniv)
- append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (ctx1_iv_off << LDST_OFFSET_SHIFT));
- }
- /* Read and write assoclen bytes */
- if (is_qi || era < 3) {
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- if (geniv)
- append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
- ivsize);
- else
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
- CAAM_CMD_SZ);
- } else {
- append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
- if (geniv)
- append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
- ivsize);
- else
- append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
- CAAM_CMD_SZ);
- }
- /* Skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* read assoc before reading payload */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
- KEY_VLF);
- if (geniv) {
- append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (ctx1_iv_off << LDST_OFFSET_SHIFT));
- append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
- (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
- }
- /* Load Counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- /* Choose operation */
- if (ctx1_iv_off)
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT);
- else
- append_dec_op1(desc, cdata->algtype);
- /* Read and write cryptlen bytes */
- append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
- /* Load ICV */
- append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
- FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR, "aead dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
- /**
- * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
- * (non-protocol) with HW-generated initialization
- * vector.
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
- * @adata: pointer to authentication transform definitions.
- * A split key is required for SEC Era < 6; the size of the split key
- * is specified in this case. Valid algorithm values - one of
- * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
- * with OP_ALG_AAI_HMAC_PRECOMP.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @nonce: pointer to rfc3686 nonce
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- * @is_qi: true when called from caam/qi
- * @era: SEC Era
- */
- void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
- struct alginfo *adata, unsigned int ivsize,
- unsigned int icvsize, const bool is_rfc3686,
- u32 *nonce, const u32 ctx1_iv_off,
- const bool is_qi, int era)
- {
- u32 geniv, moveiv;
- u32 *wait_cmd;
- /* Note: Context registers are saved. */
- init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- }
- if (is_rfc3686) {
- if (is_qi)
- append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (ctx1_iv_off << LDST_OFFSET_SHIFT));
- goto copy_iv;
- }
- /* Generate IV */
- geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
- NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
- NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
- append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
- LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- append_move(desc, MOVE_WAITCOMP |
- MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
- (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
- (ivsize << MOVE_LEN_SHIFT));
- append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
- copy_iv:
- /* Copy IV to class 1 context */
- append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
- (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
- (ivsize << MOVE_LEN_SHIFT));
- /* Return to encryption */
- append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Read and write assoclen bytes */
- if (is_qi || era < 3) {
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- } else {
- append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
- }
- /* Skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* read assoc before reading payload */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
- KEY_VLF);
- /* Copy iv from outfifo to class 2 fifo */
- moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
- NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
- append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
- LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
- append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
- LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
- /* Load Counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Will write ivsize + cryptlen */
- append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* Not need to reload iv */
- append_seq_fifo_load(desc, ivsize,
- FIFOLD_CLASS_SKIP);
- /* Will read cryptlen */
- append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /*
- * Wait for IV transfer (ofifo -> class2) to finish before starting
- * ciphertext transfer (ofifo -> external memory).
- */
- wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_cmd);
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
- FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
- /* Write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "aead givenc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
- /**
- * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
- *zero_assoc_jump_cmd2;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* skip key loading if they are loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
- ivsize);
- } else {
- append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
- CAAM_CMD_SZ);
- }
- /* if assoclen + cryptlen is ZERO, skip to ICV write */
- zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
- JUMP_COND_MATH_Z);
- if (is_qi)
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- /* if assoclen is ZERO, skip reading the assoc data */
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
- JUMP_COND_MATH_Z);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- /* skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* cryptlen = seqinlen - assoclen */
- append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
- /* if cryptlen is ZERO jump to zero-payload commands */
- zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
- JUMP_COND_MATH_Z);
- /* read assoc data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
- set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
- append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* write encrypted data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
- /* read payload data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
- /* jump to ICV writing */
- if (is_qi)
- append_jump(desc, JUMP_TEST_ALL | 4);
- else
- append_jump(desc, JUMP_TEST_ALL | 2);
- /* zero-payload commands */
- set_jump_tgt_here(desc, zero_payload_jump_cmd);
- /* read assoc data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
- if (is_qi)
- /* jump to ICV writing */
- append_jump(desc, JUMP_TEST_ALL | 2);
- /* There is no input data */
- set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
- if (is_qi)
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
- FIFOLD_TYPE_LAST1);
- /* write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR, "gcm enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
- /**
- * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* skip key loading if they are loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL |
- JUMP_TEST_ALL | JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_ICV_ON);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- }
- /* if assoclen is ZERO, skip reading the assoc data */
- append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
- zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
- JUMP_COND_MATH_Z);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- /* skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* read assoc data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
- set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
- /* cryptlen = seqoutlen - assoclen */
- append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* jump to zero-payload command if cryptlen is zero */
- zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
- JUMP_COND_MATH_Z);
- append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* store encrypted data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
- /* read payload data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
- /* zero-payload command */
- set_jump_tgt_here(desc, zero_payload_jump_cmd);
- /* read ICV */
- append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR, "gcm dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
- /**
- * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip key loading if it is loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- /* Read salt and IV */
- append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
- cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV);
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- }
- append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- /* Read assoc data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
- /* Skip IV */
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
- /* Will read cryptlen bytes */
- append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
- /* Skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* cryptlen = seqoutlen - assoclen */
- append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
- /* Write encrypted data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
- /* Read payload data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
- /* Write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "rfc4106 enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
- /**
- * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip key loading if it is loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_ICV_ON);
- if (is_qi) {
- u32 *wait_load_cmd;
- /* REG3 = assoclen */
- append_seq_load(desc, 4, LDST_CLASS_DECO |
- LDST_SRCDST_WORD_DECO_MATH3 |
- (4 << LDST_OFFSET_SHIFT));
- wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_CALM | JUMP_COND_NCP |
- JUMP_COND_NOP | JUMP_COND_NIP |
- JUMP_COND_NIFP);
- set_jump_tgt_here(desc, wait_load_cmd);
- /* Read salt and IV */
- append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
- cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV);
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- }
- append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
- /* Read assoc data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
- /* Skip IV */
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
- /* Will read cryptlen bytes */
- append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
- /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
- /* Skip assoc data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
- /* Will write cryptlen bytes */
- append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* Store payload data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
- /* Read encrypted data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
- FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
- /* Read ICV */
- append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "rfc4106 dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
- /**
- * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip key loading if it is loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- if (is_qi) {
- /* assoclen is not needed, skip it */
- append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
- /* Read salt and IV */
- append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
- cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV);
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- }
- /* assoclen + cryptlen = seqinlen */
- append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
- /*
- * MOVE_LEN opcode is not available in all SEC HW revisions,
- * thus need to do some magic, i.e. self-patch the descriptor
- * buffer.
- */
- read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
- (0x6 << MOVE_LEN_SHIFT));
- write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
- (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
- /* Will read assoclen + cryptlen bytes */
- append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* Will write assoclen + cryptlen bytes */
- append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- /* Read and write assoclen + cryptlen bytes */
- aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
- set_move_tgt_here(desc, read_move_cmd);
- set_move_tgt_here(desc, write_move_cmd);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- /* Move payload data to OFIFO */
- append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
- /* Write ICV */
- append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "rfc4543 enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
- /**
- * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
- * (non-protocol).
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
- * @ivsize: initialization vector size
- * @icvsize: integrity check value (ICV) size (truncated or full)
- * @is_qi: true when called from caam/qi
- */
- void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, unsigned int icvsize,
- const bool is_qi)
- {
- u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL);
- /* Skip key loading if it is loaded due to sharing */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- if (cdata->key_inline)
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- else
- append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
- KEY_DEST_CLASS_REG);
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Class 1 operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT | OP_ALG_ICV_ON);
- if (is_qi) {
- /* assoclen is not needed, skip it */
- append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
- /* Read salt and IV */
- append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
- cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV);
- append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
- }
- /* assoclen + cryptlen = seqoutlen */
- append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /*
- * MOVE_LEN opcode is not available in all SEC HW revisions,
- * thus need to do some magic, i.e. self-patch the descriptor
- * buffer.
- */
- read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
- (0x6 << MOVE_LEN_SHIFT));
- write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
- (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
- /* Will read assoclen + cryptlen bytes */
- append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* Will write assoclen + cryptlen bytes */
- append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
- /* Store payload data */
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
- /* In-snoop assoclen + cryptlen data */
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
- FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
- set_move_tgt_here(desc, read_move_cmd);
- set_move_tgt_here(desc, write_move_cmd);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- /* Move payload data to OFIFO */
- append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
- append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
- /* Read ICV */
- append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
- FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "rfc4543 dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
- /*
- * For ablkcipher encrypt and decrypt, read from req->src and
- * write to req->dst
- */
- static inline void ablkcipher_append_src_dst(u32 *desc)
- {
- append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
- append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
- KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
- append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
- }
- /**
- * cnstr_shdsc_ablkcipher_encap - ablkcipher encapsulation shared descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
- * @ivsize: initialization vector size
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- */
- void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, const bool is_rfc3686,
- const u32 ctx1_iv_off)
- {
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- /* Load nonce into CONTEXT1 reg */
- if (is_rfc3686) {
- const u8 *nonce = cdata->key_virt + cdata->keylen;
- append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
- LDST_CLASS_IND_CCB |
- LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
- append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
- MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
- (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Load iv */
- append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
- LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
- /* Load counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- /* Load operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Perform operation */
- ablkcipher_append_src_dst(desc);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "ablkcipher enc shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_encap);
- /**
- * cnstr_shdsc_ablkcipher_decap - ablkcipher decapsulation shared descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
- * @ivsize: initialization vector size
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- */
- void cnstr_shdsc_ablkcipher_decap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, const bool is_rfc3686,
- const u32 ctx1_iv_off)
- {
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- /* Load nonce into CONTEXT1 reg */
- if (is_rfc3686) {
- const u8 *nonce = cdata->key_virt + cdata->keylen;
- append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
- LDST_CLASS_IND_CCB |
- LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
- append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
- MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
- (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- /* load IV */
- append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
- LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
- /* Load counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- /* Choose operation */
- if (ctx1_iv_off)
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_DECRYPT);
- else
- append_dec_op1(desc, cdata->algtype);
- /* Perform operation */
- ablkcipher_append_src_dst(desc);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "ablkcipher dec shdesc@" __stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_decap);
- /**
- * cnstr_shdsc_ablkcipher_givencap - ablkcipher encapsulation shared descriptor
- * with HW-generated initialization vector.
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
- * with OP_ALG_AAI_CBC.
- * @ivsize: initialization vector size
- * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
- * @ctx1_iv_off: IV offset in CONTEXT1 register
- */
- void cnstr_shdsc_ablkcipher_givencap(u32 * const desc, struct alginfo *cdata,
- unsigned int ivsize, const bool is_rfc3686,
- const u32 ctx1_iv_off)
- {
- u32 *key_jump_cmd, geniv;
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- /* Load Nonce into CONTEXT1 reg */
- if (is_rfc3686) {
- const u8 *nonce = cdata->key_virt + cdata->keylen;
- append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
- LDST_CLASS_IND_CCB |
- LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
- append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
- MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
- (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
- }
- set_jump_tgt_here(desc, key_jump_cmd);
- /* Generate IV */
- geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
- NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | NFIFOENTRY_PTYPE_RND |
- (ivsize << NFIFOENTRY_DLEN_SHIFT);
- append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
- LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
- append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
- append_move(desc, MOVE_WAITCOMP | MOVE_SRC_INFIFO |
- MOVE_DEST_CLASS1CTX | (ivsize << MOVE_LEN_SHIFT) |
- (ctx1_iv_off << MOVE_OFFSET_SHIFT));
- append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
- /* Copy generated IV to memory */
- append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
- LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
- /* Load Counter into CONTEXT1 reg */
- if (is_rfc3686)
- append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
- LDST_OFFSET_SHIFT));
- if (ctx1_iv_off)
- append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
- (1 << JUMP_OFFSET_SHIFT));
- /* Load operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Perform operation */
- ablkcipher_append_src_dst(desc);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_givencap);
- /**
- * cnstr_shdsc_xts_ablkcipher_encap - xts ablkcipher encapsulation shared
- * descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
- */
- void cnstr_shdsc_xts_ablkcipher_encap(u32 * const desc, struct alginfo *cdata)
- {
- /*
- * Set sector size to a big value, practically disabling
- * sector size segmentation in xts implementation. We cannot
- * take full advantage of this HW feature with existing
- * crypto API / dm-crypt SW architecture.
- */
- __be64 sector_size = cpu_to_be64(BIT(15));
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /* Load class1 keys only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- /* Load sector size with index 40 bytes (0x28) */
- append_load_as_imm(desc, (void *)§or_size, 8, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (0x28 << LDST_OFFSET_SHIFT));
- set_jump_tgt_here(desc, key_jump_cmd);
- /*
- * create sequence for loading the sector index
- * Upper 8B of IV - will be used as sector index
- * Lower 8B of IV - will be discarded
- */
- append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
- (0x20 << LDST_OFFSET_SHIFT));
- append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
- /* Load operation */
- append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
- OP_ALG_ENCRYPT);
- /* Perform operation */
- ablkcipher_append_src_dst(desc);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "xts ablkcipher enc shdesc@" __stringify(__LINE__) ": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_encap);
- /**
- * cnstr_shdsc_xts_ablkcipher_decap - xts ablkcipher decapsulation shared
- * descriptor
- * @desc: pointer to buffer used for descriptor construction
- * @cdata: pointer to block cipher transform definitions
- * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
- */
- void cnstr_shdsc_xts_ablkcipher_decap(u32 * const desc, struct alginfo *cdata)
- {
- /*
- * Set sector size to a big value, practically disabling
- * sector size segmentation in xts implementation. We cannot
- * take full advantage of this HW feature with existing
- * crypto API / dm-crypt SW architecture.
- */
- __be64 sector_size = cpu_to_be64(BIT(15));
- u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
- /* Skip if already shared */
- key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
- JUMP_COND_SHRD);
- /* Load class1 key only */
- append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
- /* Load sector size with index 40 bytes (0x28) */
- append_load_as_imm(desc, (void *)§or_size, 8, LDST_CLASS_1_CCB |
- LDST_SRCDST_BYTE_CONTEXT |
- (0x28 << LDST_OFFSET_SHIFT));
- set_jump_tgt_here(desc, key_jump_cmd);
- /*
- * create sequence for loading the sector index
- * Upper 8B of IV - will be used as sector index
- * Lower 8B of IV - will be discarded
- */
- append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
- (0x20 << LDST_OFFSET_SHIFT));
- append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
- /* Load operation */
- append_dec_op1(desc, cdata->algtype);
- /* Perform operation */
- ablkcipher_append_src_dst(desc);
- #ifdef DEBUG
- print_hex_dump(KERN_ERR,
- "xts ablkcipher dec shdesc@" __stringify(__LINE__) ": ",
- DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
- #endif
- }
- EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_decap);
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("FSL CAAM descriptor support");
- MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
|