caamalg_desc.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. /*
  2. * Shared descriptors for aead, ablkcipher algorithms
  3. *
  4. * Copyright 2016 NXP
  5. */
  6. #include "compat.h"
  7. #include "desc_constr.h"
  8. #include "caamalg_desc.h"
  9. /*
  10. * For aead functions, read payload and write payload,
  11. * both of which are specified in req->src and req->dst
  12. */
  13. static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
  14. {
  15. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  16. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
  17. KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
  18. }
  19. /* Set DK bit in class 1 operation if shared */
  20. static inline void append_dec_op1(u32 *desc, u32 type)
  21. {
  22. u32 *jump_cmd, *uncond_jump_cmd;
  23. /* DK bit is valid only for AES */
  24. if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
  25. append_operation(desc, type | OP_ALG_AS_INITFINAL |
  26. OP_ALG_DECRYPT);
  27. return;
  28. }
  29. jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
  30. append_operation(desc, type | OP_ALG_AS_INITFINAL |
  31. OP_ALG_DECRYPT);
  32. uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
  33. set_jump_tgt_here(desc, jump_cmd);
  34. append_operation(desc, type | OP_ALG_AS_INITFINAL |
  35. OP_ALG_DECRYPT | OP_ALG_AAI_DK);
  36. set_jump_tgt_here(desc, uncond_jump_cmd);
  37. }
  38. /**
  39. * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
  40. * (non-protocol) with no (null) encryption.
  41. * @desc: pointer to buffer used for descriptor construction
  42. * @adata: pointer to authentication transform definitions. Note that since a
  43. * split key is to be used, the size of the split key itself is
  44. * specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
  45. * SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
  46. * @icvsize: integrity check value (ICV) size (truncated or full)
  47. *
  48. * Note: Requires an MDHA split key.
  49. */
  50. void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
  51. unsigned int icvsize)
  52. {
  53. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  54. init_sh_desc(desc, HDR_SHARE_SERIAL);
  55. /* Skip if already shared */
  56. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  57. JUMP_COND_SHRD);
  58. if (adata->key_inline)
  59. append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
  60. adata->keylen, CLASS_2 | KEY_DEST_MDHA_SPLIT |
  61. KEY_ENC);
  62. else
  63. append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
  64. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  65. set_jump_tgt_here(desc, key_jump_cmd);
  66. /* assoclen + cryptlen = seqinlen */
  67. append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  68. /* Prepare to read and write cryptlen + assoclen bytes */
  69. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  70. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  71. /*
  72. * MOVE_LEN opcode is not available in all SEC HW revisions,
  73. * thus need to do some magic, i.e. self-patch the descriptor
  74. * buffer.
  75. */
  76. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
  77. MOVE_DEST_MATH3 |
  78. (0x6 << MOVE_LEN_SHIFT));
  79. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
  80. MOVE_DEST_DESCBUF |
  81. MOVE_WAITCOMP |
  82. (0x8 << MOVE_LEN_SHIFT));
  83. /* Class 2 operation */
  84. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  85. OP_ALG_ENCRYPT);
  86. /* Read and write cryptlen bytes */
  87. aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  88. set_move_tgt_here(desc, read_move_cmd);
  89. set_move_tgt_here(desc, write_move_cmd);
  90. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  91. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
  92. MOVE_AUX_LS);
  93. /* Write ICV */
  94. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  95. LDST_SRCDST_BYTE_CONTEXT);
  96. #ifdef DEBUG
  97. print_hex_dump(KERN_ERR,
  98. "aead null enc shdesc@" __stringify(__LINE__)": ",
  99. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  100. #endif
  101. }
  102. EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
  103. /**
  104. * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
  105. * (non-protocol) with no (null) decryption.
  106. * @desc: pointer to buffer used for descriptor construction
  107. * @adata: pointer to authentication transform definitions. Note that since a
  108. * split key is to be used, the size of the split key itself is
  109. * specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
  110. * SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
  111. * @icvsize: integrity check value (ICV) size (truncated or full)
  112. *
  113. * Note: Requires an MDHA split key.
  114. */
  115. void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
  116. unsigned int icvsize)
  117. {
  118. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
  119. init_sh_desc(desc, HDR_SHARE_SERIAL);
  120. /* Skip if already shared */
  121. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  122. JUMP_COND_SHRD);
  123. if (adata->key_inline)
  124. append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
  125. adata->keylen, CLASS_2 |
  126. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  127. else
  128. append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
  129. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  130. set_jump_tgt_here(desc, key_jump_cmd);
  131. /* Class 2 operation */
  132. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  133. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  134. /* assoclen + cryptlen = seqoutlen */
  135. append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  136. /* Prepare to read and write cryptlen + assoclen bytes */
  137. append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
  138. append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
  139. /*
  140. * MOVE_LEN opcode is not available in all SEC HW revisions,
  141. * thus need to do some magic, i.e. self-patch the descriptor
  142. * buffer.
  143. */
  144. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
  145. MOVE_DEST_MATH2 |
  146. (0x6 << MOVE_LEN_SHIFT));
  147. write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
  148. MOVE_DEST_DESCBUF |
  149. MOVE_WAITCOMP |
  150. (0x8 << MOVE_LEN_SHIFT));
  151. /* Read and write cryptlen bytes */
  152. aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  153. /*
  154. * Insert a NOP here, since we need at least 4 instructions between
  155. * code patching the descriptor buffer and the location being patched.
  156. */
  157. jump_cmd = append_jump(desc, JUMP_TEST_ALL);
  158. set_jump_tgt_here(desc, jump_cmd);
  159. set_move_tgt_here(desc, read_move_cmd);
  160. set_move_tgt_here(desc, write_move_cmd);
  161. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  162. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
  163. MOVE_AUX_LS);
  164. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  165. /* Load ICV */
  166. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
  167. FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
  168. #ifdef DEBUG
  169. print_hex_dump(KERN_ERR,
  170. "aead null dec shdesc@" __stringify(__LINE__)": ",
  171. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  172. #endif
  173. }
  174. EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
  175. static void init_sh_desc_key_aead(u32 * const desc,
  176. struct alginfo * const cdata,
  177. struct alginfo * const adata,
  178. const bool is_rfc3686, u32 *nonce)
  179. {
  180. u32 *key_jump_cmd;
  181. unsigned int enckeylen = cdata->keylen;
  182. /* Note: Context registers are saved. */
  183. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  184. /* Skip if already shared */
  185. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  186. JUMP_COND_SHRD);
  187. /*
  188. * RFC3686 specific:
  189. * | key = {AUTH_KEY, ENC_KEY, NONCE}
  190. * | enckeylen = encryption key size + nonce size
  191. */
  192. if (is_rfc3686)
  193. enckeylen -= CTR_RFC3686_NONCE_SIZE;
  194. if (adata->key_inline)
  195. append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
  196. adata->keylen, CLASS_2 |
  197. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  198. else
  199. append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
  200. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  201. if (cdata->key_inline)
  202. append_key_as_imm(desc, cdata->key_virt, enckeylen,
  203. enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
  204. else
  205. append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
  206. KEY_DEST_CLASS_REG);
  207. /* Load Counter into CONTEXT1 reg */
  208. if (is_rfc3686) {
  209. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  210. LDST_CLASS_IND_CCB |
  211. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  212. append_move(desc,
  213. MOVE_SRC_OUTFIFO |
  214. MOVE_DEST_CLASS1CTX |
  215. (16 << MOVE_OFFSET_SHIFT) |
  216. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  217. }
  218. set_jump_tgt_here(desc, key_jump_cmd);
  219. }
  220. /**
  221. * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
  222. * (non-protocol).
  223. * @desc: pointer to buffer used for descriptor construction
  224. * @cdata: pointer to block cipher transform definitions
  225. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  226. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  227. * @adata: pointer to authentication transform definitions. Note that since a
  228. * split key is to be used, the size of the split key itself is
  229. * specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
  230. * SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
  231. * @ivsize: initialization vector size
  232. * @icvsize: integrity check value (ICV) size (truncated or full)
  233. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  234. * @nonce: pointer to rfc3686 nonce
  235. * @ctx1_iv_off: IV offset in CONTEXT1 register
  236. * @is_qi: true when called from caam/qi
  237. *
  238. * Note: Requires an MDHA split key.
  239. */
  240. void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
  241. struct alginfo *adata, unsigned int ivsize,
  242. unsigned int icvsize, const bool is_rfc3686,
  243. u32 *nonce, const u32 ctx1_iv_off, const bool is_qi)
  244. {
  245. /* Note: Context registers are saved. */
  246. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
  247. /* Class 2 operation */
  248. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  249. OP_ALG_ENCRYPT);
  250. if (is_qi) {
  251. u32 *wait_load_cmd;
  252. /* REG3 = assoclen */
  253. append_seq_load(desc, 4, LDST_CLASS_DECO |
  254. LDST_SRCDST_WORD_DECO_MATH3 |
  255. (4 << LDST_OFFSET_SHIFT));
  256. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  257. JUMP_COND_CALM | JUMP_COND_NCP |
  258. JUMP_COND_NOP | JUMP_COND_NIP |
  259. JUMP_COND_NIFP);
  260. set_jump_tgt_here(desc, wait_load_cmd);
  261. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  262. LDST_SRCDST_BYTE_CONTEXT |
  263. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  264. }
  265. /* Read and write assoclen bytes */
  266. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  267. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  268. /* Skip assoc data */
  269. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  270. /* read assoc before reading payload */
  271. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  272. FIFOLDST_VLF);
  273. /* Load Counter into CONTEXT1 reg */
  274. if (is_rfc3686)
  275. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  276. LDST_SRCDST_BYTE_CONTEXT |
  277. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  278. LDST_OFFSET_SHIFT));
  279. /* Class 1 operation */
  280. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  281. OP_ALG_ENCRYPT);
  282. /* Read and write cryptlen bytes */
  283. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  284. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  285. aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
  286. /* Write ICV */
  287. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  288. LDST_SRCDST_BYTE_CONTEXT);
  289. #ifdef DEBUG
  290. print_hex_dump(KERN_ERR, "aead enc shdesc@" __stringify(__LINE__)": ",
  291. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  292. #endif
  293. }
  294. EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
  295. /**
  296. * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
  297. * (non-protocol).
  298. * @desc: pointer to buffer used for descriptor construction
  299. * @cdata: pointer to block cipher transform definitions
  300. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  301. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  302. * @adata: pointer to authentication transform definitions. Note that since a
  303. * split key is to be used, the size of the split key itself is
  304. * specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
  305. * SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
  306. * @ivsize: initialization vector size
  307. * @icvsize: integrity check value (ICV) size (truncated or full)
  308. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  309. * @nonce: pointer to rfc3686 nonce
  310. * @ctx1_iv_off: IV offset in CONTEXT1 register
  311. * @is_qi: true when called from caam/qi
  312. *
  313. * Note: Requires an MDHA split key.
  314. */
  315. void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
  316. struct alginfo *adata, unsigned int ivsize,
  317. unsigned int icvsize, const bool geniv,
  318. const bool is_rfc3686, u32 *nonce,
  319. const u32 ctx1_iv_off, const bool is_qi)
  320. {
  321. /* Note: Context registers are saved. */
  322. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
  323. /* Class 2 operation */
  324. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  325. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  326. if (is_qi) {
  327. u32 *wait_load_cmd;
  328. /* REG3 = assoclen */
  329. append_seq_load(desc, 4, LDST_CLASS_DECO |
  330. LDST_SRCDST_WORD_DECO_MATH3 |
  331. (4 << LDST_OFFSET_SHIFT));
  332. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  333. JUMP_COND_CALM | JUMP_COND_NCP |
  334. JUMP_COND_NOP | JUMP_COND_NIP |
  335. JUMP_COND_NIFP);
  336. set_jump_tgt_here(desc, wait_load_cmd);
  337. if (!geniv)
  338. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  339. LDST_SRCDST_BYTE_CONTEXT |
  340. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  341. }
  342. /* Read and write assoclen bytes */
  343. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  344. if (geniv)
  345. append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize);
  346. else
  347. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  348. /* Skip assoc data */
  349. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  350. /* read assoc before reading payload */
  351. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  352. KEY_VLF);
  353. if (geniv) {
  354. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  355. LDST_SRCDST_BYTE_CONTEXT |
  356. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  357. append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
  358. (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
  359. }
  360. /* Load Counter into CONTEXT1 reg */
  361. if (is_rfc3686)
  362. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  363. LDST_SRCDST_BYTE_CONTEXT |
  364. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  365. LDST_OFFSET_SHIFT));
  366. /* Choose operation */
  367. if (ctx1_iv_off)
  368. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  369. OP_ALG_DECRYPT);
  370. else
  371. append_dec_op1(desc, cdata->algtype);
  372. /* Read and write cryptlen bytes */
  373. append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  374. append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  375. aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
  376. /* Load ICV */
  377. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
  378. FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
  379. #ifdef DEBUG
  380. print_hex_dump(KERN_ERR, "aead dec shdesc@" __stringify(__LINE__)": ",
  381. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  382. #endif
  383. }
  384. EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
  385. /**
  386. * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
  387. * (non-protocol) with HW-generated initialization
  388. * vector.
  389. * @desc: pointer to buffer used for descriptor construction
  390. * @cdata: pointer to block cipher transform definitions
  391. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  392. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  393. * @adata: pointer to authentication transform definitions. Note that since a
  394. * split key is to be used, the size of the split key itself is
  395. * specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
  396. * SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
  397. * @ivsize: initialization vector size
  398. * @icvsize: integrity check value (ICV) size (truncated or full)
  399. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  400. * @nonce: pointer to rfc3686 nonce
  401. * @ctx1_iv_off: IV offset in CONTEXT1 register
  402. * @is_qi: true when called from caam/qi
  403. *
  404. * Note: Requires an MDHA split key.
  405. */
  406. void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
  407. struct alginfo *adata, unsigned int ivsize,
  408. unsigned int icvsize, const bool is_rfc3686,
  409. u32 *nonce, const u32 ctx1_iv_off,
  410. const bool is_qi)
  411. {
  412. u32 geniv, moveiv;
  413. /* Note: Context registers are saved. */
  414. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
  415. if (is_qi) {
  416. u32 *wait_load_cmd;
  417. /* REG3 = assoclen */
  418. append_seq_load(desc, 4, LDST_CLASS_DECO |
  419. LDST_SRCDST_WORD_DECO_MATH3 |
  420. (4 << LDST_OFFSET_SHIFT));
  421. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  422. JUMP_COND_CALM | JUMP_COND_NCP |
  423. JUMP_COND_NOP | JUMP_COND_NIP |
  424. JUMP_COND_NIFP);
  425. set_jump_tgt_here(desc, wait_load_cmd);
  426. }
  427. if (is_rfc3686) {
  428. if (is_qi)
  429. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  430. LDST_SRCDST_BYTE_CONTEXT |
  431. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  432. goto copy_iv;
  433. }
  434. /* Generate IV */
  435. geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
  436. NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
  437. NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
  438. append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
  439. LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
  440. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  441. append_move(desc, MOVE_WAITCOMP |
  442. MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
  443. (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
  444. (ivsize << MOVE_LEN_SHIFT));
  445. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  446. copy_iv:
  447. /* Copy IV to class 1 context */
  448. append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
  449. (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
  450. (ivsize << MOVE_LEN_SHIFT));
  451. /* Return to encryption */
  452. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  453. OP_ALG_ENCRYPT);
  454. /* Read and write assoclen bytes */
  455. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  456. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  457. /* Skip assoc data */
  458. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  459. /* read assoc before reading payload */
  460. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  461. KEY_VLF);
  462. /* Copy iv from outfifo to class 2 fifo */
  463. moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
  464. NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
  465. append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
  466. LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
  467. append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
  468. LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
  469. /* Load Counter into CONTEXT1 reg */
  470. if (is_rfc3686)
  471. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  472. LDST_SRCDST_BYTE_CONTEXT |
  473. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  474. LDST_OFFSET_SHIFT));
  475. /* Class 1 operation */
  476. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  477. OP_ALG_ENCRYPT);
  478. /* Will write ivsize + cryptlen */
  479. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  480. /* Not need to reload iv */
  481. append_seq_fifo_load(desc, ivsize,
  482. FIFOLD_CLASS_SKIP);
  483. /* Will read cryptlen */
  484. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  485. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
  486. FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
  487. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  488. /* Write ICV */
  489. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  490. LDST_SRCDST_BYTE_CONTEXT);
  491. #ifdef DEBUG
  492. print_hex_dump(KERN_ERR,
  493. "aead givenc shdesc@" __stringify(__LINE__)": ",
  494. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  495. #endif
  496. }
  497. EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
  498. /**
  499. * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
  500. * @desc: pointer to buffer used for descriptor construction
  501. * @cdata: pointer to block cipher transform definitions
  502. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  503. * @icvsize: integrity check value (ICV) size (truncated or full)
  504. */
  505. void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
  506. unsigned int icvsize)
  507. {
  508. u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
  509. *zero_assoc_jump_cmd2;
  510. init_sh_desc(desc, HDR_SHARE_SERIAL);
  511. /* skip key loading if they are loaded due to sharing */
  512. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  513. JUMP_COND_SHRD);
  514. if (cdata->key_inline)
  515. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  516. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  517. else
  518. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  519. KEY_DEST_CLASS_REG);
  520. set_jump_tgt_here(desc, key_jump_cmd);
  521. /* class 1 operation */
  522. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  523. OP_ALG_ENCRYPT);
  524. /* if assoclen + cryptlen is ZERO, skip to ICV write */
  525. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  526. zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
  527. JUMP_COND_MATH_Z);
  528. /* if assoclen is ZERO, skip reading the assoc data */
  529. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  530. zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
  531. JUMP_COND_MATH_Z);
  532. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  533. /* skip assoc data */
  534. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  535. /* cryptlen = seqinlen - assoclen */
  536. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
  537. /* if cryptlen is ZERO jump to zero-payload commands */
  538. zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
  539. JUMP_COND_MATH_Z);
  540. /* read assoc data */
  541. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  542. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  543. set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
  544. append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  545. /* write encrypted data */
  546. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  547. /* read payload data */
  548. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  549. FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  550. /* jump the zero-payload commands */
  551. append_jump(desc, JUMP_TEST_ALL | 2);
  552. /* zero-payload commands */
  553. set_jump_tgt_here(desc, zero_payload_jump_cmd);
  554. /* read assoc data */
  555. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  556. FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
  557. /* There is no input data */
  558. set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
  559. /* write ICV */
  560. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  561. LDST_SRCDST_BYTE_CONTEXT);
  562. #ifdef DEBUG
  563. print_hex_dump(KERN_ERR, "gcm enc shdesc@" __stringify(__LINE__)": ",
  564. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  565. #endif
  566. }
  567. EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
  568. /**
  569. * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
  570. * @desc: pointer to buffer used for descriptor construction
  571. * @cdata: pointer to block cipher transform definitions
  572. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  573. * @icvsize: integrity check value (ICV) size (truncated or full)
  574. */
  575. void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
  576. unsigned int icvsize)
  577. {
  578. u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
  579. init_sh_desc(desc, HDR_SHARE_SERIAL);
  580. /* skip key loading if they are loaded due to sharing */
  581. key_jump_cmd = append_jump(desc, JUMP_JSL |
  582. JUMP_TEST_ALL | JUMP_COND_SHRD);
  583. if (cdata->key_inline)
  584. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  585. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  586. else
  587. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  588. KEY_DEST_CLASS_REG);
  589. set_jump_tgt_here(desc, key_jump_cmd);
  590. /* class 1 operation */
  591. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  592. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  593. /* if assoclen is ZERO, skip reading the assoc data */
  594. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  595. zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
  596. JUMP_COND_MATH_Z);
  597. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  598. /* skip assoc data */
  599. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  600. /* read assoc data */
  601. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  602. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  603. set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
  604. /* cryptlen = seqoutlen - assoclen */
  605. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  606. /* jump to zero-payload command if cryptlen is zero */
  607. zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
  608. JUMP_COND_MATH_Z);
  609. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  610. /* store encrypted data */
  611. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  612. /* read payload data */
  613. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  614. FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  615. /* zero-payload command */
  616. set_jump_tgt_here(desc, zero_payload_jump_cmd);
  617. /* read ICV */
  618. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  619. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  620. #ifdef DEBUG
  621. print_hex_dump(KERN_ERR, "gcm dec shdesc@" __stringify(__LINE__)": ",
  622. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  623. #endif
  624. }
  625. EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
  626. /**
  627. * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
  628. * (non-protocol).
  629. * @desc: pointer to buffer used for descriptor construction
  630. * @cdata: pointer to block cipher transform definitions
  631. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  632. * @icvsize: integrity check value (ICV) size (truncated or full)
  633. */
  634. void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
  635. unsigned int icvsize)
  636. {
  637. u32 *key_jump_cmd;
  638. init_sh_desc(desc, HDR_SHARE_SERIAL);
  639. /* Skip key loading if it is loaded due to sharing */
  640. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  641. JUMP_COND_SHRD);
  642. if (cdata->key_inline)
  643. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  644. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  645. else
  646. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  647. KEY_DEST_CLASS_REG);
  648. set_jump_tgt_here(desc, key_jump_cmd);
  649. /* Class 1 operation */
  650. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  651. OP_ALG_ENCRYPT);
  652. append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
  653. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  654. /* Read assoc data */
  655. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  656. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  657. /* Skip IV */
  658. append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
  659. /* Will read cryptlen bytes */
  660. append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  661. /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
  662. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
  663. /* Skip assoc data */
  664. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  665. /* cryptlen = seqoutlen - assoclen */
  666. append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
  667. /* Write encrypted data */
  668. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  669. /* Read payload data */
  670. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  671. FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  672. /* Write ICV */
  673. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  674. LDST_SRCDST_BYTE_CONTEXT);
  675. #ifdef DEBUG
  676. print_hex_dump(KERN_ERR,
  677. "rfc4106 enc shdesc@" __stringify(__LINE__)": ",
  678. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  679. #endif
  680. }
  681. EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
  682. /**
  683. * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
  684. * (non-protocol).
  685. * @desc: pointer to buffer used for descriptor construction
  686. * @cdata: pointer to block cipher transform definitions
  687. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  688. * @icvsize: integrity check value (ICV) size (truncated or full)
  689. */
  690. void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
  691. unsigned int icvsize)
  692. {
  693. u32 *key_jump_cmd;
  694. init_sh_desc(desc, HDR_SHARE_SERIAL);
  695. /* Skip key loading if it is loaded due to sharing */
  696. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  697. JUMP_COND_SHRD);
  698. if (cdata->key_inline)
  699. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  700. cdata->keylen, CLASS_1 |
  701. KEY_DEST_CLASS_REG);
  702. else
  703. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  704. KEY_DEST_CLASS_REG);
  705. set_jump_tgt_here(desc, key_jump_cmd);
  706. /* Class 1 operation */
  707. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  708. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  709. append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
  710. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  711. /* Read assoc data */
  712. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  713. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  714. /* Skip IV */
  715. append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
  716. /* Will read cryptlen bytes */
  717. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
  718. /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
  719. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
  720. /* Skip assoc data */
  721. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  722. /* Will write cryptlen bytes */
  723. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  724. /* Store payload data */
  725. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  726. /* Read encrypted data */
  727. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  728. FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  729. /* Read ICV */
  730. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  731. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  732. #ifdef DEBUG
  733. print_hex_dump(KERN_ERR,
  734. "rfc4106 dec shdesc@" __stringify(__LINE__)": ",
  735. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  736. #endif
  737. }
  738. EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
  739. /**
  740. * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
  741. * (non-protocol).
  742. * @desc: pointer to buffer used for descriptor construction
  743. * @cdata: pointer to block cipher transform definitions
  744. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  745. * @icvsize: integrity check value (ICV) size (truncated or full)
  746. */
  747. void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
  748. unsigned int icvsize)
  749. {
  750. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  751. init_sh_desc(desc, HDR_SHARE_SERIAL);
  752. /* Skip key loading if it is loaded due to sharing */
  753. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  754. JUMP_COND_SHRD);
  755. if (cdata->key_inline)
  756. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  757. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  758. else
  759. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  760. KEY_DEST_CLASS_REG);
  761. set_jump_tgt_here(desc, key_jump_cmd);
  762. /* Class 1 operation */
  763. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  764. OP_ALG_ENCRYPT);
  765. /* assoclen + cryptlen = seqinlen */
  766. append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  767. /*
  768. * MOVE_LEN opcode is not available in all SEC HW revisions,
  769. * thus need to do some magic, i.e. self-patch the descriptor
  770. * buffer.
  771. */
  772. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
  773. (0x6 << MOVE_LEN_SHIFT));
  774. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
  775. (0x8 << MOVE_LEN_SHIFT));
  776. /* Will read assoclen + cryptlen bytes */
  777. append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  778. /* Will write assoclen + cryptlen bytes */
  779. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  780. /* Read and write assoclen + cryptlen bytes */
  781. aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
  782. set_move_tgt_here(desc, read_move_cmd);
  783. set_move_tgt_here(desc, write_move_cmd);
  784. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  785. /* Move payload data to OFIFO */
  786. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
  787. /* Write ICV */
  788. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  789. LDST_SRCDST_BYTE_CONTEXT);
  790. #ifdef DEBUG
  791. print_hex_dump(KERN_ERR,
  792. "rfc4543 enc shdesc@" __stringify(__LINE__)": ",
  793. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  794. #endif
  795. }
  796. EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
  797. /**
  798. * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
  799. * (non-protocol).
  800. * @desc: pointer to buffer used for descriptor construction
  801. * @cdata: pointer to block cipher transform definitions
  802. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  803. * @icvsize: integrity check value (ICV) size (truncated or full)
  804. */
  805. void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
  806. unsigned int icvsize)
  807. {
  808. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  809. init_sh_desc(desc, HDR_SHARE_SERIAL);
  810. /* Skip key loading if it is loaded due to sharing */
  811. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  812. JUMP_COND_SHRD);
  813. if (cdata->key_inline)
  814. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  815. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  816. else
  817. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  818. KEY_DEST_CLASS_REG);
  819. set_jump_tgt_here(desc, key_jump_cmd);
  820. /* Class 1 operation */
  821. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  822. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  823. /* assoclen + cryptlen = seqoutlen */
  824. append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  825. /*
  826. * MOVE_LEN opcode is not available in all SEC HW revisions,
  827. * thus need to do some magic, i.e. self-patch the descriptor
  828. * buffer.
  829. */
  830. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
  831. (0x6 << MOVE_LEN_SHIFT));
  832. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
  833. (0x8 << MOVE_LEN_SHIFT));
  834. /* Will read assoclen + cryptlen bytes */
  835. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  836. /* Will write assoclen + cryptlen bytes */
  837. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  838. /* Store payload data */
  839. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  840. /* In-snoop assoclen + cryptlen data */
  841. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
  842. FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
  843. set_move_tgt_here(desc, read_move_cmd);
  844. set_move_tgt_here(desc, write_move_cmd);
  845. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  846. /* Move payload data to OFIFO */
  847. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
  848. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  849. /* Read ICV */
  850. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  851. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  852. #ifdef DEBUG
  853. print_hex_dump(KERN_ERR,
  854. "rfc4543 dec shdesc@" __stringify(__LINE__)": ",
  855. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  856. #endif
  857. }
  858. EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
  859. /*
  860. * For ablkcipher encrypt and decrypt, read from req->src and
  861. * write to req->dst
  862. */
  863. static inline void ablkcipher_append_src_dst(u32 *desc)
  864. {
  865. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  866. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  867. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
  868. KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  869. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  870. }
  871. /**
  872. * cnstr_shdsc_ablkcipher_encap - ablkcipher encapsulation shared descriptor
  873. * @desc: pointer to buffer used for descriptor construction
  874. * @cdata: pointer to block cipher transform definitions
  875. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  876. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  877. * @ivsize: initialization vector size
  878. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  879. * @ctx1_iv_off: IV offset in CONTEXT1 register
  880. */
  881. void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
  882. unsigned int ivsize, const bool is_rfc3686,
  883. const u32 ctx1_iv_off)
  884. {
  885. u32 *key_jump_cmd;
  886. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  887. /* Skip if already shared */
  888. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  889. JUMP_COND_SHRD);
  890. /* Load class1 key only */
  891. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  892. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  893. /* Load nonce into CONTEXT1 reg */
  894. if (is_rfc3686) {
  895. u8 *nonce = cdata->key_virt + cdata->keylen;
  896. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  897. LDST_CLASS_IND_CCB |
  898. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  899. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
  900. MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
  901. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  902. }
  903. set_jump_tgt_here(desc, key_jump_cmd);
  904. /* Load iv */
  905. append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  906. LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
  907. /* Load counter into CONTEXT1 reg */
  908. if (is_rfc3686)
  909. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  910. LDST_SRCDST_BYTE_CONTEXT |
  911. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  912. LDST_OFFSET_SHIFT));
  913. /* Load operation */
  914. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  915. OP_ALG_ENCRYPT);
  916. /* Perform operation */
  917. ablkcipher_append_src_dst(desc);
  918. #ifdef DEBUG
  919. print_hex_dump(KERN_ERR,
  920. "ablkcipher enc shdesc@" __stringify(__LINE__)": ",
  921. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  922. #endif
  923. }
  924. EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_encap);
  925. /**
  926. * cnstr_shdsc_ablkcipher_decap - ablkcipher decapsulation shared descriptor
  927. * @desc: pointer to buffer used for descriptor construction
  928. * @cdata: pointer to block cipher transform definitions
  929. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  930. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  931. * @ivsize: initialization vector size
  932. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  933. * @ctx1_iv_off: IV offset in CONTEXT1 register
  934. */
  935. void cnstr_shdsc_ablkcipher_decap(u32 * const desc, struct alginfo *cdata,
  936. unsigned int ivsize, const bool is_rfc3686,
  937. const u32 ctx1_iv_off)
  938. {
  939. u32 *key_jump_cmd;
  940. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  941. /* Skip if already shared */
  942. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  943. JUMP_COND_SHRD);
  944. /* Load class1 key only */
  945. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  946. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  947. /* Load nonce into CONTEXT1 reg */
  948. if (is_rfc3686) {
  949. u8 *nonce = cdata->key_virt + cdata->keylen;
  950. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  951. LDST_CLASS_IND_CCB |
  952. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  953. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
  954. MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
  955. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  956. }
  957. set_jump_tgt_here(desc, key_jump_cmd);
  958. /* load IV */
  959. append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  960. LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
  961. /* Load counter into CONTEXT1 reg */
  962. if (is_rfc3686)
  963. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  964. LDST_SRCDST_BYTE_CONTEXT |
  965. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  966. LDST_OFFSET_SHIFT));
  967. /* Choose operation */
  968. if (ctx1_iv_off)
  969. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  970. OP_ALG_DECRYPT);
  971. else
  972. append_dec_op1(desc, cdata->algtype);
  973. /* Perform operation */
  974. ablkcipher_append_src_dst(desc);
  975. #ifdef DEBUG
  976. print_hex_dump(KERN_ERR,
  977. "ablkcipher dec shdesc@" __stringify(__LINE__)": ",
  978. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  979. #endif
  980. }
  981. EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_decap);
  982. /**
  983. * cnstr_shdsc_ablkcipher_givencap - ablkcipher encapsulation shared descriptor
  984. * with HW-generated initialization vector.
  985. * @desc: pointer to buffer used for descriptor construction
  986. * @cdata: pointer to block cipher transform definitions
  987. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  988. * with OP_ALG_AAI_CBC.
  989. * @ivsize: initialization vector size
  990. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  991. * @ctx1_iv_off: IV offset in CONTEXT1 register
  992. */
  993. void cnstr_shdsc_ablkcipher_givencap(u32 * const desc, struct alginfo *cdata,
  994. unsigned int ivsize, const bool is_rfc3686,
  995. const u32 ctx1_iv_off)
  996. {
  997. u32 *key_jump_cmd, geniv;
  998. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  999. /* Skip if already shared */
  1000. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1001. JUMP_COND_SHRD);
  1002. /* Load class1 key only */
  1003. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1004. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  1005. /* Load Nonce into CONTEXT1 reg */
  1006. if (is_rfc3686) {
  1007. u8 *nonce = cdata->key_virt + cdata->keylen;
  1008. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  1009. LDST_CLASS_IND_CCB |
  1010. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  1011. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
  1012. MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
  1013. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  1014. }
  1015. set_jump_tgt_here(desc, key_jump_cmd);
  1016. /* Generate IV */
  1017. geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
  1018. NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | NFIFOENTRY_PTYPE_RND |
  1019. (ivsize << NFIFOENTRY_DLEN_SHIFT);
  1020. append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
  1021. LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
  1022. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  1023. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_INFIFO |
  1024. MOVE_DEST_CLASS1CTX | (ivsize << MOVE_LEN_SHIFT) |
  1025. (ctx1_iv_off << MOVE_OFFSET_SHIFT));
  1026. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  1027. /* Copy generated IV to memory */
  1028. append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1029. LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
  1030. /* Load Counter into CONTEXT1 reg */
  1031. if (is_rfc3686)
  1032. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  1033. LDST_SRCDST_BYTE_CONTEXT |
  1034. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  1035. LDST_OFFSET_SHIFT));
  1036. if (ctx1_iv_off)
  1037. append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
  1038. (1 << JUMP_OFFSET_SHIFT));
  1039. /* Load operation */
  1040. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  1041. OP_ALG_ENCRYPT);
  1042. /* Perform operation */
  1043. ablkcipher_append_src_dst(desc);
  1044. #ifdef DEBUG
  1045. print_hex_dump(KERN_ERR,
  1046. "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
  1047. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  1048. #endif
  1049. }
  1050. EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_givencap);
  1051. /**
  1052. * cnstr_shdsc_xts_ablkcipher_encap - xts ablkcipher encapsulation shared
  1053. * descriptor
  1054. * @desc: pointer to buffer used for descriptor construction
  1055. * @cdata: pointer to block cipher transform definitions
  1056. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
  1057. */
  1058. void cnstr_shdsc_xts_ablkcipher_encap(u32 * const desc, struct alginfo *cdata)
  1059. {
  1060. __be64 sector_size = cpu_to_be64(512);
  1061. u32 *key_jump_cmd;
  1062. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1063. /* Skip if already shared */
  1064. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1065. JUMP_COND_SHRD);
  1066. /* Load class1 keys only */
  1067. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1068. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  1069. /* Load sector size with index 40 bytes (0x28) */
  1070. append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
  1071. LDST_SRCDST_BYTE_CONTEXT |
  1072. (0x28 << LDST_OFFSET_SHIFT));
  1073. set_jump_tgt_here(desc, key_jump_cmd);
  1074. /*
  1075. * create sequence for loading the sector index
  1076. * Upper 8B of IV - will be used as sector index
  1077. * Lower 8B of IV - will be discarded
  1078. */
  1079. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1080. (0x20 << LDST_OFFSET_SHIFT));
  1081. append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
  1082. /* Load operation */
  1083. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  1084. OP_ALG_ENCRYPT);
  1085. /* Perform operation */
  1086. ablkcipher_append_src_dst(desc);
  1087. #ifdef DEBUG
  1088. print_hex_dump(KERN_ERR,
  1089. "xts ablkcipher enc shdesc@" __stringify(__LINE__) ": ",
  1090. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  1091. #endif
  1092. }
  1093. EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_encap);
  1094. /**
  1095. * cnstr_shdsc_xts_ablkcipher_decap - xts ablkcipher decapsulation shared
  1096. * descriptor
  1097. * @desc: pointer to buffer used for descriptor construction
  1098. * @cdata: pointer to block cipher transform definitions
  1099. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
  1100. */
  1101. void cnstr_shdsc_xts_ablkcipher_decap(u32 * const desc, struct alginfo *cdata)
  1102. {
  1103. __be64 sector_size = cpu_to_be64(512);
  1104. u32 *key_jump_cmd;
  1105. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1106. /* Skip if already shared */
  1107. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1108. JUMP_COND_SHRD);
  1109. /* Load class1 key only */
  1110. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1111. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  1112. /* Load sector size with index 40 bytes (0x28) */
  1113. append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
  1114. LDST_SRCDST_BYTE_CONTEXT |
  1115. (0x28 << LDST_OFFSET_SHIFT));
  1116. set_jump_tgt_here(desc, key_jump_cmd);
  1117. /*
  1118. * create sequence for loading the sector index
  1119. * Upper 8B of IV - will be used as sector index
  1120. * Lower 8B of IV - will be discarded
  1121. */
  1122. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1123. (0x20 << LDST_OFFSET_SHIFT));
  1124. append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
  1125. /* Load operation */
  1126. append_dec_op1(desc, cdata->algtype);
  1127. /* Perform operation */
  1128. ablkcipher_append_src_dst(desc);
  1129. #ifdef DEBUG
  1130. print_hex_dump(KERN_ERR,
  1131. "xts ablkcipher dec shdesc@" __stringify(__LINE__) ": ",
  1132. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
  1133. #endif
  1134. }
  1135. EXPORT_SYMBOL(cnstr_shdsc_xts_ablkcipher_decap);
  1136. MODULE_LICENSE("GPL");
  1137. MODULE_DESCRIPTION("FSL CAAM descriptor support");
  1138. MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");