caamalg_desc.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Shared descriptors for aead, skcipher algorithms
  4. *
  5. * Copyright 2016-2019, 2025 NXP
  6. */
  7. #include "compat.h"
  8. #include "desc_constr.h"
  9. #include "caamalg_desc.h"
  10. #include <soc/fsl/caam-blob.h>
  11. /*
  12. * For aead functions, read payload and write payload,
  13. * both of which are specified in req->src and req->dst
  14. */
  15. static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
  16. {
  17. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  18. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
  19. KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
  20. }
  21. /* Set DK bit in class 1 operation if shared */
  22. static inline void append_dec_op1(u32 *desc, u32 type)
  23. {
  24. u32 *jump_cmd, *uncond_jump_cmd;
  25. /* DK bit is valid only for AES */
  26. if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
  27. append_operation(desc, type | OP_ALG_AS_INITFINAL |
  28. OP_ALG_DECRYPT);
  29. return;
  30. }
  31. jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
  32. append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
  33. uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
  34. set_jump_tgt_here(desc, jump_cmd);
  35. append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
  36. OP_ALG_AAI_DK);
  37. set_jump_tgt_here(desc, uncond_jump_cmd);
  38. }
  39. /**
  40. * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
  41. * (non-protocol) with no (null) encryption.
  42. * @desc: pointer to buffer used for descriptor construction
  43. * @adata: pointer to authentication transform definitions.
  44. * A split key is required for SEC Era < 6; the size of the split key
  45. * is specified in this case. Valid algorithm values - one of
  46. * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  47. * with OP_ALG_AAI_HMAC_PRECOMP.
  48. * @icvsize: integrity check value (ICV) size (truncated or full)
  49. * @era: SEC Era
  50. */
  51. void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
  52. unsigned int icvsize, int era)
  53. {
  54. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  55. init_sh_desc(desc, HDR_SHARE_SERIAL);
  56. /* Skip if already shared */
  57. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  58. JUMP_COND_SHRD);
  59. if (era < 6) {
  60. if (adata->key_inline)
  61. append_key_as_imm(desc, adata->key_virt,
  62. adata->keylen_pad, adata->keylen,
  63. CLASS_2 | KEY_DEST_MDHA_SPLIT |
  64. KEY_ENC);
  65. else
  66. append_key(desc, adata->key_dma, adata->keylen,
  67. CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
  68. } else {
  69. append_proto_dkp(desc, adata);
  70. }
  71. set_jump_tgt_here(desc, key_jump_cmd);
  72. /* assoclen + cryptlen = seqinlen */
  73. append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  74. /* Prepare to read and write cryptlen + assoclen bytes */
  75. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  76. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  77. /*
  78. * MOVE_LEN opcode is not available in all SEC HW revisions,
  79. * thus need to do some magic, i.e. self-patch the descriptor
  80. * buffer.
  81. */
  82. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
  83. MOVE_DEST_MATH3 |
  84. (0x6 << MOVE_LEN_SHIFT));
  85. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
  86. MOVE_DEST_DESCBUF |
  87. MOVE_WAITCOMP |
  88. (0x8 << MOVE_LEN_SHIFT));
  89. /* Class 2 operation */
  90. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  91. OP_ALG_ENCRYPT);
  92. /* Read and write cryptlen bytes */
  93. aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  94. set_move_tgt_here(desc, read_move_cmd);
  95. set_move_tgt_here(desc, write_move_cmd);
  96. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  97. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
  98. MOVE_AUX_LS);
  99. /* Write ICV */
  100. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  101. LDST_SRCDST_BYTE_CONTEXT);
  102. print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
  103. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  104. 1);
  105. }
  106. EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
  107. /**
  108. * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
  109. * (non-protocol) with no (null) decryption.
  110. * @desc: pointer to buffer used for descriptor construction
  111. * @adata: pointer to authentication transform definitions.
  112. * A split key is required for SEC Era < 6; the size of the split key
  113. * is specified in this case. Valid algorithm values - one of
  114. * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  115. * with OP_ALG_AAI_HMAC_PRECOMP.
  116. * @icvsize: integrity check value (ICV) size (truncated or full)
  117. * @era: SEC Era
  118. */
  119. void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
  120. unsigned int icvsize, int era)
  121. {
  122. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
  123. init_sh_desc(desc, HDR_SHARE_SERIAL);
  124. /* Skip if already shared */
  125. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  126. JUMP_COND_SHRD);
  127. if (era < 6) {
  128. if (adata->key_inline)
  129. append_key_as_imm(desc, adata->key_virt,
  130. adata->keylen_pad, adata->keylen,
  131. CLASS_2 | KEY_DEST_MDHA_SPLIT |
  132. KEY_ENC);
  133. else
  134. append_key(desc, adata->key_dma, adata->keylen,
  135. CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
  136. } else {
  137. append_proto_dkp(desc, adata);
  138. }
  139. set_jump_tgt_here(desc, key_jump_cmd);
  140. /* Class 2 operation */
  141. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  142. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  143. /* assoclen + cryptlen = seqoutlen */
  144. append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  145. /* Prepare to read and write cryptlen + assoclen bytes */
  146. append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
  147. append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
  148. /*
  149. * MOVE_LEN opcode is not available in all SEC HW revisions,
  150. * thus need to do some magic, i.e. self-patch the descriptor
  151. * buffer.
  152. */
  153. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
  154. MOVE_DEST_MATH2 |
  155. (0x6 << MOVE_LEN_SHIFT));
  156. write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
  157. MOVE_DEST_DESCBUF |
  158. MOVE_WAITCOMP |
  159. (0x8 << MOVE_LEN_SHIFT));
  160. /* Read and write cryptlen bytes */
  161. aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  162. /*
  163. * Insert a NOP here, since we need at least 4 instructions between
  164. * code patching the descriptor buffer and the location being patched.
  165. */
  166. jump_cmd = append_jump(desc, JUMP_TEST_ALL);
  167. set_jump_tgt_here(desc, jump_cmd);
  168. set_move_tgt_here(desc, read_move_cmd);
  169. set_move_tgt_here(desc, write_move_cmd);
  170. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  171. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
  172. MOVE_AUX_LS);
  173. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  174. /* Load ICV */
  175. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
  176. FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
  177. print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
  178. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  179. 1);
  180. }
  181. EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
  182. static void init_sh_desc_key_aead(u32 * const desc,
  183. struct alginfo * const cdata,
  184. struct alginfo * const adata,
  185. const bool is_rfc3686, u32 *nonce, int era)
  186. {
  187. u32 *key_jump_cmd;
  188. unsigned int enckeylen = cdata->keylen;
  189. /* Note: Context registers are saved. */
  190. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  191. /* Skip if already shared */
  192. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  193. JUMP_COND_SHRD);
  194. /*
  195. * RFC3686 specific:
  196. * | key = {AUTH_KEY, ENC_KEY, NONCE}
  197. * | enckeylen = encryption key size + nonce size
  198. */
  199. if (is_rfc3686)
  200. enckeylen -= CTR_RFC3686_NONCE_SIZE;
  201. if (era < 6) {
  202. if (adata->key_inline)
  203. append_key_as_imm(desc, adata->key_virt,
  204. adata->keylen_pad, adata->keylen,
  205. CLASS_2 | KEY_DEST_MDHA_SPLIT |
  206. KEY_ENC);
  207. else
  208. append_key(desc, adata->key_dma, adata->keylen,
  209. CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
  210. } else {
  211. append_proto_dkp(desc, adata);
  212. }
  213. if (cdata->key_inline)
  214. append_key_as_imm(desc, cdata->key_virt, enckeylen,
  215. enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
  216. else
  217. append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
  218. KEY_DEST_CLASS_REG);
  219. /* Load Counter into CONTEXT1 reg */
  220. if (is_rfc3686) {
  221. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  222. LDST_CLASS_IND_CCB |
  223. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  224. append_move(desc,
  225. MOVE_SRC_OUTFIFO |
  226. MOVE_DEST_CLASS1CTX |
  227. (16 << MOVE_OFFSET_SHIFT) |
  228. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  229. }
  230. set_jump_tgt_here(desc, key_jump_cmd);
  231. }
  232. /**
  233. * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
  234. * (non-protocol).
  235. * @desc: pointer to buffer used for descriptor construction
  236. * @cdata: pointer to block cipher transform definitions
  237. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  238. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  239. * @adata: pointer to authentication transform definitions.
  240. * A split key is required for SEC Era < 6; the size of the split key
  241. * is specified in this case. Valid algorithm values - one of
  242. * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  243. * with OP_ALG_AAI_HMAC_PRECOMP.
  244. * @ivsize: initialization vector size
  245. * @icvsize: integrity check value (ICV) size (truncated or full)
  246. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  247. * @nonce: pointer to rfc3686 nonce
  248. * @ctx1_iv_off: IV offset in CONTEXT1 register
  249. * @is_qi: true when called from caam/qi
  250. * @era: SEC Era
  251. */
  252. void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
  253. struct alginfo *adata, unsigned int ivsize,
  254. unsigned int icvsize, const bool is_rfc3686,
  255. u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
  256. int era)
  257. {
  258. /* Note: Context registers are saved. */
  259. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
  260. /* Class 2 operation */
  261. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  262. OP_ALG_ENCRYPT);
  263. if (is_qi) {
  264. u32 *wait_load_cmd;
  265. /* REG3 = assoclen */
  266. append_seq_load(desc, 4, LDST_CLASS_DECO |
  267. LDST_SRCDST_WORD_DECO_MATH3 |
  268. (4 << LDST_OFFSET_SHIFT));
  269. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  270. JUMP_COND_CALM | JUMP_COND_NCP |
  271. JUMP_COND_NOP | JUMP_COND_NIP |
  272. JUMP_COND_NIFP);
  273. set_jump_tgt_here(desc, wait_load_cmd);
  274. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  275. LDST_SRCDST_BYTE_CONTEXT |
  276. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  277. }
  278. /* Read and write assoclen bytes */
  279. if (is_qi || era < 3) {
  280. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  281. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  282. } else {
  283. append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
  284. append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
  285. }
  286. /* Skip assoc data */
  287. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  288. /* read assoc before reading payload */
  289. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  290. FIFOLDST_VLF);
  291. /* Load Counter into CONTEXT1 reg */
  292. if (is_rfc3686)
  293. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  294. LDST_SRCDST_BYTE_CONTEXT |
  295. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  296. LDST_OFFSET_SHIFT));
  297. /* Class 1 operation */
  298. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  299. OP_ALG_ENCRYPT);
  300. /* Read and write cryptlen bytes */
  301. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  302. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  303. aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
  304. /* Write ICV */
  305. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  306. LDST_SRCDST_BYTE_CONTEXT);
  307. print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
  308. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  309. 1);
  310. }
  311. EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
  312. /**
  313. * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
  314. * (non-protocol).
  315. * @desc: pointer to buffer used for descriptor construction
  316. * @cdata: pointer to block cipher transform definitions
  317. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  318. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  319. * @adata: pointer to authentication transform definitions.
  320. * A split key is required for SEC Era < 6; the size of the split key
  321. * is specified in this case. Valid algorithm values - one of
  322. * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  323. * with OP_ALG_AAI_HMAC_PRECOMP.
  324. * @ivsize: initialization vector size
  325. * @icvsize: integrity check value (ICV) size (truncated or full)
  326. * @geniv: whether to generate Encrypted Chain IV
  327. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  328. * @nonce: pointer to rfc3686 nonce
  329. * @ctx1_iv_off: IV offset in CONTEXT1 register
  330. * @is_qi: true when called from caam/qi
  331. * @era: SEC Era
  332. */
  333. void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
  334. struct alginfo *adata, unsigned int ivsize,
  335. unsigned int icvsize, const bool geniv,
  336. const bool is_rfc3686, u32 *nonce,
  337. const u32 ctx1_iv_off, const bool is_qi, int era)
  338. {
  339. /* Note: Context registers are saved. */
  340. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
  341. /* Class 2 operation */
  342. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  343. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  344. if (is_qi) {
  345. u32 *wait_load_cmd;
  346. /* REG3 = assoclen */
  347. append_seq_load(desc, 4, LDST_CLASS_DECO |
  348. LDST_SRCDST_WORD_DECO_MATH3 |
  349. (4 << LDST_OFFSET_SHIFT));
  350. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  351. JUMP_COND_CALM | JUMP_COND_NCP |
  352. JUMP_COND_NOP | JUMP_COND_NIP |
  353. JUMP_COND_NIFP);
  354. set_jump_tgt_here(desc, wait_load_cmd);
  355. if (!geniv)
  356. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  357. LDST_SRCDST_BYTE_CONTEXT |
  358. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  359. }
  360. /* Read and write assoclen bytes */
  361. if (is_qi || era < 3) {
  362. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  363. if (geniv)
  364. append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
  365. ivsize);
  366. else
  367. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
  368. CAAM_CMD_SZ);
  369. } else {
  370. append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
  371. if (geniv)
  372. append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
  373. ivsize);
  374. else
  375. append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
  376. CAAM_CMD_SZ);
  377. }
  378. /* Skip assoc data */
  379. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  380. /* read assoc before reading payload */
  381. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  382. KEY_VLF);
  383. if (geniv) {
  384. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  385. LDST_SRCDST_BYTE_CONTEXT |
  386. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  387. append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
  388. (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
  389. }
  390. /* Load Counter into CONTEXT1 reg */
  391. if (is_rfc3686)
  392. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  393. LDST_SRCDST_BYTE_CONTEXT |
  394. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  395. LDST_OFFSET_SHIFT));
  396. /* Choose operation */
  397. if (ctx1_iv_off)
  398. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  399. OP_ALG_DECRYPT);
  400. else
  401. append_dec_op1(desc, cdata->algtype);
  402. /* Read and write cryptlen bytes */
  403. append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  404. append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  405. aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
  406. /* Load ICV */
  407. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
  408. FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
  409. print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
  410. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  411. 1);
  412. }
  413. EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
  414. /**
  415. * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
  416. * (non-protocol) with HW-generated initialization
  417. * vector.
  418. * @desc: pointer to buffer used for descriptor construction
  419. * @cdata: pointer to block cipher transform definitions
  420. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  421. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
  422. * @adata: pointer to authentication transform definitions.
  423. * A split key is required for SEC Era < 6; the size of the split key
  424. * is specified in this case. Valid algorithm values - one of
  425. * OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  426. * with OP_ALG_AAI_HMAC_PRECOMP.
  427. * @ivsize: initialization vector size
  428. * @icvsize: integrity check value (ICV) size (truncated or full)
  429. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  430. * @nonce: pointer to rfc3686 nonce
  431. * @ctx1_iv_off: IV offset in CONTEXT1 register
  432. * @is_qi: true when called from caam/qi
  433. * @era: SEC Era
  434. */
  435. void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
  436. struct alginfo *adata, unsigned int ivsize,
  437. unsigned int icvsize, const bool is_rfc3686,
  438. u32 *nonce, const u32 ctx1_iv_off,
  439. const bool is_qi, int era)
  440. {
  441. u32 geniv, moveiv;
  442. u32 *wait_cmd;
  443. /* Note: Context registers are saved. */
  444. init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
  445. if (is_qi) {
  446. u32 *wait_load_cmd;
  447. /* REG3 = assoclen */
  448. append_seq_load(desc, 4, LDST_CLASS_DECO |
  449. LDST_SRCDST_WORD_DECO_MATH3 |
  450. (4 << LDST_OFFSET_SHIFT));
  451. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  452. JUMP_COND_CALM | JUMP_COND_NCP |
  453. JUMP_COND_NOP | JUMP_COND_NIP |
  454. JUMP_COND_NIFP);
  455. set_jump_tgt_here(desc, wait_load_cmd);
  456. }
  457. if (is_rfc3686) {
  458. if (is_qi)
  459. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  460. LDST_SRCDST_BYTE_CONTEXT |
  461. (ctx1_iv_off << LDST_OFFSET_SHIFT));
  462. goto copy_iv;
  463. }
  464. /* Generate IV */
  465. geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
  466. NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
  467. NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
  468. append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
  469. LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
  470. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  471. append_move(desc, MOVE_WAITCOMP |
  472. MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
  473. (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
  474. (ivsize << MOVE_LEN_SHIFT));
  475. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  476. copy_iv:
  477. /* Copy IV to class 1 context */
  478. append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
  479. (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
  480. (ivsize << MOVE_LEN_SHIFT));
  481. /* Return to encryption */
  482. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  483. OP_ALG_ENCRYPT);
  484. /* Read and write assoclen bytes */
  485. if (is_qi || era < 3) {
  486. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  487. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  488. } else {
  489. append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
  490. append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
  491. }
  492. /* Skip assoc data */
  493. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  494. /* read assoc before reading payload */
  495. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
  496. KEY_VLF);
  497. /* Copy iv from outfifo to class 2 fifo */
  498. moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
  499. NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
  500. append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
  501. LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
  502. append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
  503. LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
  504. /* Load Counter into CONTEXT1 reg */
  505. if (is_rfc3686)
  506. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  507. LDST_SRCDST_BYTE_CONTEXT |
  508. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  509. LDST_OFFSET_SHIFT));
  510. /* Class 1 operation */
  511. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  512. OP_ALG_ENCRYPT);
  513. /* Will write ivsize + cryptlen */
  514. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  515. /* Not need to reload iv */
  516. append_seq_fifo_load(desc, ivsize,
  517. FIFOLD_CLASS_SKIP);
  518. /* Will read cryptlen */
  519. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  520. /*
  521. * Wait for IV transfer (ofifo -> class2) to finish before starting
  522. * ciphertext transfer (ofifo -> external memory).
  523. */
  524. wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
  525. set_jump_tgt_here(desc, wait_cmd);
  526. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
  527. FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
  528. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  529. /* Write ICV */
  530. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  531. LDST_SRCDST_BYTE_CONTEXT);
  532. print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
  533. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  534. 1);
  535. }
  536. EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
  537. /**
  538. * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
  539. * @desc: pointer to buffer used for descriptor construction
  540. * @cdata: pointer to block cipher transform definitions
  541. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  542. * @ivsize: initialization vector size
  543. * @icvsize: integrity check value (ICV) size (truncated or full)
  544. * @is_qi: true when called from caam/qi
  545. */
  546. void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
  547. unsigned int ivsize, unsigned int icvsize,
  548. const bool is_qi)
  549. {
  550. u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
  551. *zero_assoc_jump_cmd2;
  552. init_sh_desc(desc, HDR_SHARE_SERIAL);
  553. /* skip key loading if they are loaded due to sharing */
  554. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  555. JUMP_COND_SHRD);
  556. if (cdata->key_inline)
  557. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  558. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  559. else
  560. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  561. KEY_DEST_CLASS_REG);
  562. set_jump_tgt_here(desc, key_jump_cmd);
  563. /* class 1 operation */
  564. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  565. OP_ALG_ENCRYPT);
  566. if (is_qi) {
  567. u32 *wait_load_cmd;
  568. /* REG3 = assoclen */
  569. append_seq_load(desc, 4, LDST_CLASS_DECO |
  570. LDST_SRCDST_WORD_DECO_MATH3 |
  571. (4 << LDST_OFFSET_SHIFT));
  572. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  573. JUMP_COND_CALM | JUMP_COND_NCP |
  574. JUMP_COND_NOP | JUMP_COND_NIP |
  575. JUMP_COND_NIFP);
  576. set_jump_tgt_here(desc, wait_load_cmd);
  577. append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
  578. ivsize);
  579. } else {
  580. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
  581. CAAM_CMD_SZ);
  582. }
  583. /* if assoclen + cryptlen is ZERO, skip to ICV write */
  584. zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
  585. JUMP_COND_MATH_Z);
  586. if (is_qi)
  587. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  588. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  589. /* if assoclen is ZERO, skip reading the assoc data */
  590. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  591. zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
  592. JUMP_COND_MATH_Z);
  593. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  594. /* skip assoc data */
  595. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  596. /* cryptlen = seqinlen - assoclen */
  597. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
  598. /* if cryptlen is ZERO jump to zero-payload commands */
  599. zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
  600. JUMP_COND_MATH_Z);
  601. /* read assoc data */
  602. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  603. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  604. set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
  605. append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  606. /* write encrypted data */
  607. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  608. /* read payload data */
  609. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  610. FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  611. /* jump to ICV writing */
  612. if (is_qi)
  613. append_jump(desc, JUMP_TEST_ALL | 4);
  614. else
  615. append_jump(desc, JUMP_TEST_ALL | 2);
  616. /* zero-payload commands */
  617. set_jump_tgt_here(desc, zero_payload_jump_cmd);
  618. /* read assoc data */
  619. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  620. FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
  621. if (is_qi)
  622. /* jump to ICV writing */
  623. append_jump(desc, JUMP_TEST_ALL | 2);
  624. /* There is no input data */
  625. set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
  626. if (is_qi)
  627. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  628. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
  629. FIFOLD_TYPE_LAST1);
  630. /* write ICV */
  631. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  632. LDST_SRCDST_BYTE_CONTEXT);
  633. print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
  634. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  635. 1);
  636. }
  637. EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
  638. /**
  639. * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
  640. * @desc: pointer to buffer used for descriptor construction
  641. * @cdata: pointer to block cipher transform definitions
  642. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  643. * @ivsize: initialization vector size
  644. * @icvsize: integrity check value (ICV) size (truncated or full)
  645. * @is_qi: true when called from caam/qi
  646. */
  647. void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
  648. unsigned int ivsize, unsigned int icvsize,
  649. const bool is_qi)
  650. {
  651. u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
  652. init_sh_desc(desc, HDR_SHARE_SERIAL);
  653. /* skip key loading if they are loaded due to sharing */
  654. key_jump_cmd = append_jump(desc, JUMP_JSL |
  655. JUMP_TEST_ALL | JUMP_COND_SHRD);
  656. if (cdata->key_inline)
  657. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  658. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  659. else
  660. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  661. KEY_DEST_CLASS_REG);
  662. set_jump_tgt_here(desc, key_jump_cmd);
  663. /* class 1 operation */
  664. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  665. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  666. if (is_qi) {
  667. u32 *wait_load_cmd;
  668. /* REG3 = assoclen */
  669. append_seq_load(desc, 4, LDST_CLASS_DECO |
  670. LDST_SRCDST_WORD_DECO_MATH3 |
  671. (4 << LDST_OFFSET_SHIFT));
  672. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  673. JUMP_COND_CALM | JUMP_COND_NCP |
  674. JUMP_COND_NOP | JUMP_COND_NIP |
  675. JUMP_COND_NIFP);
  676. set_jump_tgt_here(desc, wait_load_cmd);
  677. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  678. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  679. }
  680. /* if assoclen is ZERO, skip reading the assoc data */
  681. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  682. zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
  683. JUMP_COND_MATH_Z);
  684. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  685. /* skip assoc data */
  686. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  687. /* read assoc data */
  688. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  689. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  690. set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
  691. /* cryptlen = seqoutlen - assoclen */
  692. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  693. /* jump to zero-payload command if cryptlen is zero */
  694. zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
  695. JUMP_COND_MATH_Z);
  696. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  697. /* store encrypted data */
  698. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  699. /* read payload data */
  700. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  701. FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  702. /* zero-payload command */
  703. set_jump_tgt_here(desc, zero_payload_jump_cmd);
  704. /* read ICV */
  705. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  706. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  707. print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
  708. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  709. 1);
  710. }
  711. EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
  712. /**
  713. * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
  714. * (non-protocol).
  715. * @desc: pointer to buffer used for descriptor construction
  716. * @cdata: pointer to block cipher transform definitions
  717. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  718. * @ivsize: initialization vector size
  719. * @icvsize: integrity check value (ICV) size (truncated or full)
  720. * @is_qi: true when called from caam/qi
  721. *
  722. * Input sequence: AAD | PTXT
  723. * Output sequence: AAD | CTXT | ICV
  724. * AAD length (assoclen), which includes the IV length, is available in Math3.
  725. */
  726. void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
  727. unsigned int ivsize, unsigned int icvsize,
  728. const bool is_qi)
  729. {
  730. u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
  731. init_sh_desc(desc, HDR_SHARE_SERIAL);
  732. /* Skip key loading if it is loaded due to sharing */
  733. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  734. JUMP_COND_SHRD);
  735. if (cdata->key_inline)
  736. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  737. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  738. else
  739. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  740. KEY_DEST_CLASS_REG);
  741. set_jump_tgt_here(desc, key_jump_cmd);
  742. /* Class 1 operation */
  743. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  744. OP_ALG_ENCRYPT);
  745. if (is_qi) {
  746. u32 *wait_load_cmd;
  747. /* REG3 = assoclen */
  748. append_seq_load(desc, 4, LDST_CLASS_DECO |
  749. LDST_SRCDST_WORD_DECO_MATH3 |
  750. (4 << LDST_OFFSET_SHIFT));
  751. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  752. JUMP_COND_CALM | JUMP_COND_NCP |
  753. JUMP_COND_NOP | JUMP_COND_NIP |
  754. JUMP_COND_NIFP);
  755. set_jump_tgt_here(desc, wait_load_cmd);
  756. /* Read salt and IV */
  757. append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
  758. cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
  759. FIFOLD_TYPE_IV);
  760. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  761. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  762. }
  763. append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
  764. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  765. /* Skip AAD */
  766. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  767. /* Read cryptlen and set this value into VARSEQOUTLEN */
  768. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
  769. /* If cryptlen is ZERO jump to AAD command */
  770. zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
  771. JUMP_COND_MATH_Z);
  772. /* Read AAD data */
  773. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  774. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  775. /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
  776. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
  777. /* Skip IV */
  778. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
  779. append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
  780. /* Write encrypted data */
  781. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  782. /* Read payload data */
  783. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  784. FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  785. /* Jump instructions to avoid double reading of AAD */
  786. skip_instructions = append_jump(desc, JUMP_TEST_ALL);
  787. /* There is no input data, cryptlen = 0 */
  788. set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
  789. /* Read AAD */
  790. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  791. FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
  792. set_jump_tgt_here(desc, skip_instructions);
  793. /* Write ICV */
  794. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  795. LDST_SRCDST_BYTE_CONTEXT);
  796. print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
  797. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  798. 1);
  799. }
  800. EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
  801. /**
  802. * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
  803. * (non-protocol).
  804. * @desc: pointer to buffer used for descriptor construction
  805. * @cdata: pointer to block cipher transform definitions
  806. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  807. * @ivsize: initialization vector size
  808. * @icvsize: integrity check value (ICV) size (truncated or full)
  809. * @is_qi: true when called from caam/qi
  810. */
  811. void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
  812. unsigned int ivsize, unsigned int icvsize,
  813. const bool is_qi)
  814. {
  815. u32 *key_jump_cmd;
  816. init_sh_desc(desc, HDR_SHARE_SERIAL);
  817. /* Skip key loading if it is loaded due to sharing */
  818. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  819. JUMP_COND_SHRD);
  820. if (cdata->key_inline)
  821. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  822. cdata->keylen, CLASS_1 |
  823. KEY_DEST_CLASS_REG);
  824. else
  825. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  826. KEY_DEST_CLASS_REG);
  827. set_jump_tgt_here(desc, key_jump_cmd);
  828. /* Class 1 operation */
  829. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  830. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  831. if (is_qi) {
  832. u32 *wait_load_cmd;
  833. /* REG3 = assoclen */
  834. append_seq_load(desc, 4, LDST_CLASS_DECO |
  835. LDST_SRCDST_WORD_DECO_MATH3 |
  836. (4 << LDST_OFFSET_SHIFT));
  837. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  838. JUMP_COND_CALM | JUMP_COND_NCP |
  839. JUMP_COND_NOP | JUMP_COND_NIP |
  840. JUMP_COND_NIFP);
  841. set_jump_tgt_here(desc, wait_load_cmd);
  842. /* Read salt and IV */
  843. append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
  844. cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
  845. FIFOLD_TYPE_IV);
  846. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  847. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  848. }
  849. append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
  850. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  851. /* Read assoc data */
  852. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  853. FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
  854. /* Skip IV */
  855. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
  856. /* Will read cryptlen bytes */
  857. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
  858. /* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
  859. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
  860. /* Skip assoc data */
  861. append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
  862. /* Will write cryptlen bytes */
  863. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  864. /* Store payload data */
  865. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  866. /* Read encrypted data */
  867. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
  868. FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
  869. /* Read ICV */
  870. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  871. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  872. print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
  873. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  874. 1);
  875. }
  876. EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
  877. /**
  878. * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
  879. * (non-protocol).
  880. * @desc: pointer to buffer used for descriptor construction
  881. * @cdata: pointer to block cipher transform definitions
  882. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  883. * @ivsize: initialization vector size
  884. * @icvsize: integrity check value (ICV) size (truncated or full)
  885. * @is_qi: true when called from caam/qi
  886. */
  887. void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
  888. unsigned int ivsize, unsigned int icvsize,
  889. const bool is_qi)
  890. {
  891. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  892. init_sh_desc(desc, HDR_SHARE_SERIAL);
  893. /* Skip key loading if it is loaded due to sharing */
  894. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  895. JUMP_COND_SHRD);
  896. if (cdata->key_inline)
  897. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  898. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  899. else
  900. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  901. KEY_DEST_CLASS_REG);
  902. set_jump_tgt_here(desc, key_jump_cmd);
  903. /* Class 1 operation */
  904. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  905. OP_ALG_ENCRYPT);
  906. if (is_qi) {
  907. /* assoclen is not needed, skip it */
  908. append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
  909. /* Read salt and IV */
  910. append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
  911. cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
  912. FIFOLD_TYPE_IV);
  913. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  914. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  915. }
  916. /* assoclen + cryptlen = seqinlen */
  917. append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  918. /*
  919. * MOVE_LEN opcode is not available in all SEC HW revisions,
  920. * thus need to do some magic, i.e. self-patch the descriptor
  921. * buffer.
  922. */
  923. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
  924. (0x6 << MOVE_LEN_SHIFT));
  925. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
  926. (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
  927. /* Will read assoclen + cryptlen bytes */
  928. append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  929. /* Will write assoclen + cryptlen bytes */
  930. append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  931. /* Read and write assoclen + cryptlen bytes */
  932. aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
  933. set_move_tgt_here(desc, read_move_cmd);
  934. set_move_tgt_here(desc, write_move_cmd);
  935. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  936. /* Move payload data to OFIFO */
  937. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
  938. /* Write ICV */
  939. append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
  940. LDST_SRCDST_BYTE_CONTEXT);
  941. print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
  942. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  943. 1);
  944. }
  945. EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
  946. /**
  947. * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
  948. * (non-protocol).
  949. * @desc: pointer to buffer used for descriptor construction
  950. * @cdata: pointer to block cipher transform definitions
  951. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
  952. * @ivsize: initialization vector size
  953. * @icvsize: integrity check value (ICV) size (truncated or full)
  954. * @is_qi: true when called from caam/qi
  955. */
  956. void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
  957. unsigned int ivsize, unsigned int icvsize,
  958. const bool is_qi)
  959. {
  960. u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  961. init_sh_desc(desc, HDR_SHARE_SERIAL);
  962. /* Skip key loading if it is loaded due to sharing */
  963. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  964. JUMP_COND_SHRD);
  965. if (cdata->key_inline)
  966. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  967. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  968. else
  969. append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
  970. KEY_DEST_CLASS_REG);
  971. set_jump_tgt_here(desc, key_jump_cmd);
  972. /* Class 1 operation */
  973. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  974. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  975. if (is_qi) {
  976. /* assoclen is not needed, skip it */
  977. append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
  978. /* Read salt and IV */
  979. append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
  980. cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
  981. FIFOLD_TYPE_IV);
  982. append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
  983. FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
  984. }
  985. /* assoclen + cryptlen = seqoutlen */
  986. append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  987. /*
  988. * MOVE_LEN opcode is not available in all SEC HW revisions,
  989. * thus need to do some magic, i.e. self-patch the descriptor
  990. * buffer.
  991. */
  992. read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
  993. (0x6 << MOVE_LEN_SHIFT));
  994. write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
  995. (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
  996. /* Will read assoclen + cryptlen bytes */
  997. append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  998. /* Will write assoclen + cryptlen bytes */
  999. append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  1000. /* Store payload data */
  1001. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
  1002. /* In-snoop assoclen + cryptlen data */
  1003. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
  1004. FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
  1005. set_move_tgt_here(desc, read_move_cmd);
  1006. set_move_tgt_here(desc, write_move_cmd);
  1007. append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
  1008. /* Move payload data to OFIFO */
  1009. append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
  1010. append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
  1011. /* Read ICV */
  1012. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
  1013. FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
  1014. print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
  1015. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  1016. 1);
  1017. }
  1018. EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
  1019. /**
  1020. * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
  1021. * IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
  1022. * descriptor (non-protocol).
  1023. * @desc: pointer to buffer used for descriptor construction
  1024. * @cdata: pointer to block cipher transform definitions
  1025. * Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
  1026. * OP_ALG_AAI_AEAD.
  1027. * @adata: pointer to authentication transform definitions
  1028. * Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
  1029. * OP_ALG_AAI_AEAD.
  1030. * @ivsize: initialization vector size
  1031. * @icvsize: integrity check value (ICV) size (truncated or full)
  1032. * @encap: true if encapsulation, false if decapsulation
  1033. * @is_qi: true when called from caam/qi
  1034. */
  1035. void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
  1036. struct alginfo *adata, unsigned int ivsize,
  1037. unsigned int icvsize, const bool encap,
  1038. const bool is_qi)
  1039. {
  1040. u32 *key_jump_cmd, *wait_cmd;
  1041. u32 nfifo;
  1042. const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
  1043. /* Note: Context registers are saved. */
  1044. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1045. /* skip key loading if they are loaded due to sharing */
  1046. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1047. JUMP_COND_SHRD);
  1048. append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
  1049. CLASS_1 | KEY_DEST_CLASS_REG);
  1050. /* For IPsec load the salt from keymat in the context register */
  1051. if (is_ipsec)
  1052. append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
  1053. LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
  1054. 4 << LDST_OFFSET_SHIFT);
  1055. set_jump_tgt_here(desc, key_jump_cmd);
  1056. /* Class 2 and 1 operations: Poly & ChaCha */
  1057. if (encap) {
  1058. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  1059. OP_ALG_ENCRYPT);
  1060. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  1061. OP_ALG_ENCRYPT);
  1062. } else {
  1063. append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
  1064. OP_ALG_DECRYPT | OP_ALG_ICV_ON);
  1065. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  1066. OP_ALG_DECRYPT);
  1067. }
  1068. if (is_qi) {
  1069. u32 *wait_load_cmd;
  1070. u32 ctx1_iv_off = is_ipsec ? 8 : 4;
  1071. /* REG3 = assoclen */
  1072. append_seq_load(desc, 4, LDST_CLASS_DECO |
  1073. LDST_SRCDST_WORD_DECO_MATH3 |
  1074. 4 << LDST_OFFSET_SHIFT);
  1075. wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1076. JUMP_COND_CALM | JUMP_COND_NCP |
  1077. JUMP_COND_NOP | JUMP_COND_NIP |
  1078. JUMP_COND_NIFP);
  1079. set_jump_tgt_here(desc, wait_load_cmd);
  1080. append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
  1081. LDST_SRCDST_BYTE_CONTEXT |
  1082. ctx1_iv_off << LDST_OFFSET_SHIFT);
  1083. }
  1084. /*
  1085. * MAGIC with NFIFO
  1086. * Read associated data from the input and send them to class1 and
  1087. * class2 alignment blocks. From class1 send data to output fifo and
  1088. * then write it to memory since we don't need to encrypt AD.
  1089. */
  1090. nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
  1091. NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
  1092. append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
  1093. LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
  1094. append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  1095. append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  1096. append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
  1097. FIFOLD_CLASS_CLASS1 | LDST_VLF);
  1098. append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
  1099. MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
  1100. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
  1101. /* IPsec - copy IV at the output */
  1102. if (is_ipsec)
  1103. append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
  1104. 0x2 << 25);
  1105. wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
  1106. JUMP_COND_NOP | JUMP_TEST_ALL);
  1107. set_jump_tgt_here(desc, wait_cmd);
  1108. if (encap) {
  1109. /* Read and write cryptlen bytes */
  1110. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  1111. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
  1112. CAAM_CMD_SZ);
  1113. aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
  1114. /* Write ICV */
  1115. append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
  1116. LDST_SRCDST_BYTE_CONTEXT);
  1117. } else {
  1118. /* Read and write cryptlen bytes */
  1119. append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
  1120. CAAM_CMD_SZ);
  1121. append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
  1122. CAAM_CMD_SZ);
  1123. aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
  1124. /* Load ICV for verification */
  1125. append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
  1126. FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
  1127. }
  1128. print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
  1129. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  1130. 1);
  1131. }
  1132. EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
  1133. /* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
  1134. static inline void skcipher_append_src_dst(u32 *desc)
  1135. {
  1136. append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  1137. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  1138. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
  1139. KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
  1140. append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  1141. }
  1142. void cnstr_desc_skcipher_enc_dec(u32 * const desc, struct alginfo *cdata,
  1143. dma_addr_t src, dma_addr_t dst, unsigned int data_sz,
  1144. unsigned int in_options, unsigned int out_options,
  1145. unsigned int ivsize, const bool encrypt)
  1146. {
  1147. u32 options = cdata->algtype | OP_ALG_AS_INIT;
  1148. if (encrypt)
  1149. options |= OP_ALG_ENCRYPT;
  1150. else
  1151. options |= OP_ALG_DECRYPT;
  1152. init_job_desc(desc, 0);
  1153. append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
  1154. JUMP_COND_NOP | JUMP_TEST_ALL | 1);
  1155. append_key(desc, cdata->protected_key_dma, cdata->plain_keylen,
  1156. CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt);
  1157. append_seq_in_ptr(desc, src, data_sz, in_options);
  1158. append_seq_out_ptr(desc, dst, data_sz, out_options);
  1159. /* Load IV, if there is one */
  1160. if (ivsize)
  1161. append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1162. LDST_CLASS_1_CCB);
  1163. append_operation(desc, options);
  1164. skcipher_append_src_dst(desc);
  1165. /* Store IV */
  1166. if (ivsize)
  1167. append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1168. LDST_CLASS_1_CCB);
  1169. print_hex_dump_debug("skcipher_enc_dec job desc@" __stringify(__LINE__)": ",
  1170. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  1171. 1);
  1172. }
  1173. EXPORT_SYMBOL(cnstr_desc_skcipher_enc_dec);
  1174. void cnstr_desc_protected_blob_decap(u32 * const desc, struct alginfo *cdata,
  1175. dma_addr_t next_desc_addr)
  1176. {
  1177. u32 protected_store;
  1178. init_job_desc(desc, 0);
  1179. /* Load key modifier */
  1180. append_load_as_imm(desc, KEYMOD, sizeof(KEYMOD) - 1,
  1181. LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
  1182. append_seq_in_ptr_intlen(desc, cdata->key_dma,
  1183. cdata->plain_keylen + CAAM_BLOB_OVERHEAD, 0);
  1184. append_seq_out_ptr_intlen(desc, cdata->protected_key_dma,
  1185. cdata->plain_keylen, 0);
  1186. protected_store = OP_PCLID_BLOB | OP_PCL_BLOB_BLACK;
  1187. if ((cdata->key_cmd_opt >> KEY_EKT_OFFSET) & 1)
  1188. protected_store |= OP_PCL_BLOB_EKT;
  1189. append_operation(desc, OP_TYPE_DECAP_PROTOCOL | protected_store);
  1190. if (next_desc_addr) {
  1191. append_jump(desc, JUMP_TYPE_NONLOCAL | JUMP_TEST_ALL);
  1192. append_ptr(desc, next_desc_addr);
  1193. }
  1194. print_hex_dump_debug("protected blob decap job desc@" __stringify(__LINE__) ":",
  1195. DUMP_PREFIX_ADDRESS, 16, 4, desc,
  1196. desc_bytes(desc), 1);
  1197. }
  1198. EXPORT_SYMBOL(cnstr_desc_protected_blob_decap);
  1199. /**
  1200. * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
  1201. * @desc: pointer to buffer used for descriptor construction
  1202. * @cdata: pointer to block cipher transform definitions
  1203. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  1204. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
  1205. * - OP_ALG_ALGSEL_CHACHA20
  1206. * @ivsize: initialization vector size
  1207. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  1208. * @ctx1_iv_off: IV offset in CONTEXT1 register
  1209. */
  1210. void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
  1211. unsigned int ivsize, const bool is_rfc3686,
  1212. const u32 ctx1_iv_off)
  1213. {
  1214. u32 *key_jump_cmd;
  1215. u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
  1216. bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
  1217. OP_ALG_ALGSEL_CHACHA20);
  1218. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1219. /* Skip if already shared */
  1220. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1221. JUMP_COND_SHRD);
  1222. /* Load class1 key only */
  1223. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1224. cdata->plain_keylen, CLASS_1 | KEY_DEST_CLASS_REG
  1225. | cdata->key_cmd_opt);
  1226. /* Load nonce into CONTEXT1 reg */
  1227. if (is_rfc3686) {
  1228. const u8 *nonce = cdata->key_virt + cdata->keylen;
  1229. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  1230. LDST_CLASS_IND_CCB |
  1231. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  1232. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
  1233. MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
  1234. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  1235. }
  1236. set_jump_tgt_here(desc, key_jump_cmd);
  1237. /* Load IV, if there is one */
  1238. if (ivsize)
  1239. append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1240. LDST_CLASS_1_CCB | (ctx1_iv_off <<
  1241. LDST_OFFSET_SHIFT));
  1242. /* Load counter into CONTEXT1 reg */
  1243. if (is_rfc3686)
  1244. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  1245. LDST_SRCDST_BYTE_CONTEXT |
  1246. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  1247. LDST_OFFSET_SHIFT));
  1248. /* Load operation */
  1249. if (is_chacha20)
  1250. options |= OP_ALG_AS_FINALIZE;
  1251. append_operation(desc, options);
  1252. /* Perform operation */
  1253. skcipher_append_src_dst(desc);
  1254. /* Store IV */
  1255. if (!is_chacha20 && ivsize)
  1256. append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1257. LDST_CLASS_1_CCB | (ctx1_iv_off <<
  1258. LDST_OFFSET_SHIFT));
  1259. print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
  1260. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  1261. 1);
  1262. }
  1263. EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
  1264. /**
  1265. * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
  1266. * @desc: pointer to buffer used for descriptor construction
  1267. * @cdata: pointer to block cipher transform definitions
  1268. * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
  1269. * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
  1270. * - OP_ALG_ALGSEL_CHACHA20
  1271. * @ivsize: initialization vector size
  1272. * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
  1273. * @ctx1_iv_off: IV offset in CONTEXT1 register
  1274. */
  1275. void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
  1276. unsigned int ivsize, const bool is_rfc3686,
  1277. const u32 ctx1_iv_off)
  1278. {
  1279. u32 *key_jump_cmd;
  1280. bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
  1281. OP_ALG_ALGSEL_CHACHA20);
  1282. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1283. /* Skip if already shared */
  1284. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1285. JUMP_COND_SHRD);
  1286. /* Load class1 key only */
  1287. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1288. cdata->plain_keylen, CLASS_1 | KEY_DEST_CLASS_REG
  1289. | cdata->key_cmd_opt);
  1290. /* Load nonce into CONTEXT1 reg */
  1291. if (is_rfc3686) {
  1292. const u8 *nonce = cdata->key_virt + cdata->keylen;
  1293. append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
  1294. LDST_CLASS_IND_CCB |
  1295. LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
  1296. append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
  1297. MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
  1298. (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
  1299. }
  1300. set_jump_tgt_here(desc, key_jump_cmd);
  1301. /* Load IV, if there is one */
  1302. if (ivsize)
  1303. append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1304. LDST_CLASS_1_CCB | (ctx1_iv_off <<
  1305. LDST_OFFSET_SHIFT));
  1306. /* Load counter into CONTEXT1 reg */
  1307. if (is_rfc3686)
  1308. append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
  1309. LDST_SRCDST_BYTE_CONTEXT |
  1310. ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
  1311. LDST_OFFSET_SHIFT));
  1312. /* Choose operation */
  1313. if (ctx1_iv_off)
  1314. append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
  1315. OP_ALG_DECRYPT);
  1316. else
  1317. append_dec_op1(desc, cdata->algtype);
  1318. /* Perform operation */
  1319. skcipher_append_src_dst(desc);
  1320. /* Store IV */
  1321. if (!is_chacha20 && ivsize)
  1322. append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
  1323. LDST_CLASS_1_CCB | (ctx1_iv_off <<
  1324. LDST_OFFSET_SHIFT));
  1325. print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
  1326. DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
  1327. 1);
  1328. }
  1329. EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
  1330. /**
  1331. * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
  1332. * @desc: pointer to buffer used for descriptor construction
  1333. * @cdata: pointer to block cipher transform definitions
  1334. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
  1335. */
  1336. void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
  1337. {
  1338. /*
  1339. * Set sector size to a big value, practically disabling
  1340. * sector size segmentation in xts implementation. We cannot
  1341. * take full advantage of this HW feature with existing
  1342. * crypto API / dm-crypt SW architecture.
  1343. */
  1344. __be64 sector_size = cpu_to_be64(BIT(15));
  1345. u32 *key_jump_cmd;
  1346. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1347. /* Skip if already shared */
  1348. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1349. JUMP_COND_SHRD);
  1350. /* Load class1 keys only */
  1351. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1352. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  1353. /* Load sector size with index 40 bytes (0x28) */
  1354. append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
  1355. LDST_SRCDST_BYTE_CONTEXT |
  1356. (0x28 << LDST_OFFSET_SHIFT));
  1357. set_jump_tgt_here(desc, key_jump_cmd);
  1358. /*
  1359. * create sequence for loading the sector index / 16B tweak value
  1360. * Lower 8B of IV - sector index / tweak lower half
  1361. * Upper 8B of IV - upper half of 16B tweak
  1362. */
  1363. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1364. (0x20 << LDST_OFFSET_SHIFT));
  1365. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1366. (0x30 << LDST_OFFSET_SHIFT));
  1367. /* Load operation */
  1368. append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
  1369. OP_ALG_ENCRYPT);
  1370. /* Perform operation */
  1371. skcipher_append_src_dst(desc);
  1372. /* Store lower 8B and upper 8B of IV */
  1373. append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1374. (0x20 << LDST_OFFSET_SHIFT));
  1375. append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1376. (0x30 << LDST_OFFSET_SHIFT));
  1377. print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
  1378. ": ", DUMP_PREFIX_ADDRESS, 16, 4,
  1379. desc, desc_bytes(desc), 1);
  1380. }
  1381. EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
  1382. /**
  1383. * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
  1384. * @desc: pointer to buffer used for descriptor construction
  1385. * @cdata: pointer to block cipher transform definitions
  1386. * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
  1387. */
  1388. void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
  1389. {
  1390. /*
  1391. * Set sector size to a big value, practically disabling
  1392. * sector size segmentation in xts implementation. We cannot
  1393. * take full advantage of this HW feature with existing
  1394. * crypto API / dm-crypt SW architecture.
  1395. */
  1396. __be64 sector_size = cpu_to_be64(BIT(15));
  1397. u32 *key_jump_cmd;
  1398. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  1399. /* Skip if already shared */
  1400. key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  1401. JUMP_COND_SHRD);
  1402. /* Load class1 key only */
  1403. append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
  1404. cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  1405. /* Load sector size with index 40 bytes (0x28) */
  1406. append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
  1407. LDST_SRCDST_BYTE_CONTEXT |
  1408. (0x28 << LDST_OFFSET_SHIFT));
  1409. set_jump_tgt_here(desc, key_jump_cmd);
  1410. /*
  1411. * create sequence for loading the sector index / 16B tweak value
  1412. * Lower 8B of IV - sector index / tweak lower half
  1413. * Upper 8B of IV - upper half of 16B tweak
  1414. */
  1415. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1416. (0x20 << LDST_OFFSET_SHIFT));
  1417. append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1418. (0x30 << LDST_OFFSET_SHIFT));
  1419. /* Load operation */
  1420. append_dec_op1(desc, cdata->algtype);
  1421. /* Perform operation */
  1422. skcipher_append_src_dst(desc);
  1423. /* Store lower 8B and upper 8B of IV */
  1424. append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1425. (0x20 << LDST_OFFSET_SHIFT));
  1426. append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
  1427. (0x30 << LDST_OFFSET_SHIFT));
  1428. print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
  1429. ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
  1430. desc_bytes(desc), 1);
  1431. }
  1432. EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
  1433. MODULE_LICENSE("GPL");
  1434. MODULE_DESCRIPTION("FSL CAAM descriptor support");
  1435. MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");