caamhash_desc.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  2. /*
  3. * Shared descriptors for ahash algorithms
  4. *
  5. * Copyright 2017-2019 NXP
  6. */
  7. #include "compat.h"
  8. #include "desc_constr.h"
  9. #include "caamhash_desc.h"
  10. /**
  11. * cnstr_shdsc_ahash - ahash shared descriptor
  12. * @desc: pointer to buffer used for descriptor construction
  13. * @adata: pointer to authentication transform definitions.
  14. * A split key is required for SEC Era < 6; the size of the split key
  15. * is specified in this case.
  16. * Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
  17. * SHA256, SHA384, SHA512}.
  18. * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
  19. * @digestsize: algorithm's digest size
  20. * @ctx_len: size of Context Register
  21. * @import_ctx: true if previous Context Register needs to be restored
  22. * must be true for ahash update and final
  23. * must be false for for ahash first and digest
  24. * @era: SEC Era
  25. */
  26. void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
  27. int digestsize, int ctx_len, bool import_ctx, int era)
  28. {
  29. u32 op = adata->algtype;
  30. init_sh_desc(desc, HDR_SHARE_SERIAL);
  31. /* Append key if it has been set; ahash update excluded */
  32. if (state != OP_ALG_AS_UPDATE && adata->keylen) {
  33. u32 *skip_key_load;
  34. /* Skip key loading if already shared */
  35. skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  36. JUMP_COND_SHRD);
  37. if (era < 6)
  38. append_key_as_imm(desc, adata->key_virt,
  39. adata->keylen_pad,
  40. adata->keylen, CLASS_2 |
  41. KEY_DEST_MDHA_SPLIT | KEY_ENC);
  42. else
  43. append_proto_dkp(desc, adata);
  44. set_jump_tgt_here(desc, skip_key_load);
  45. op |= OP_ALG_AAI_HMAC_PRECOMP;
  46. }
  47. /* If needed, import context from software */
  48. if (import_ctx)
  49. append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
  50. LDST_SRCDST_BYTE_CONTEXT);
  51. /* Class 2 operation */
  52. append_operation(desc, op | state | OP_ALG_ENCRYPT);
  53. /*
  54. * Load from buf and/or src and write to req->result or state->context
  55. * Calculate remaining bytes to read
  56. */
  57. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  58. /* Read remaining bytes */
  59. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
  60. FIFOLD_TYPE_MSG | KEY_VLF);
  61. /* Store class2 context bytes */
  62. append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
  63. LDST_SRCDST_BYTE_CONTEXT);
  64. }
  65. EXPORT_SYMBOL(cnstr_shdsc_ahash);
  66. /**
  67. * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
  68. * hash algorithms
  69. * @desc: pointer to buffer used for descriptor construction
  70. * @adata: pointer to authentication transform definitions.
  71. * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
  72. * @digestsize: algorithm's digest size
  73. * @ctx_len: size of Context Register
  74. */
  75. void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
  76. int digestsize, int ctx_len)
  77. {
  78. u32 *skip_key_load;
  79. init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  80. /* Skip loading of key, context if already shared */
  81. skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
  82. if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
  83. append_key_as_imm(desc, adata->key_virt, adata->keylen,
  84. adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
  85. } else { /* UPDATE, FINALIZE */
  86. if (is_xcbc_aes(adata->algtype))
  87. /* Load K1 */
  88. append_key(desc, adata->key_dma, adata->keylen,
  89. CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
  90. else /* CMAC */
  91. append_key_as_imm(desc, adata->key_virt, adata->keylen,
  92. adata->keylen, CLASS_1 |
  93. KEY_DEST_CLASS_REG);
  94. /* Restore context */
  95. append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
  96. LDST_SRCDST_BYTE_CONTEXT);
  97. }
  98. set_jump_tgt_here(desc, skip_key_load);
  99. /* Class 1 operation */
  100. append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
  101. /*
  102. * Load from buf and/or src and write to req->result or state->context
  103. * Calculate remaining bytes to read
  104. */
  105. append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  106. /* Read remaining bytes */
  107. append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
  108. FIFOLD_TYPE_MSG | FIFOLDST_VLF);
  109. /*
  110. * Save context:
  111. * - xcbc: partial hash, keys K2 and K3
  112. * - cmac: partial hash, constant L = E(K,0)
  113. */
  114. append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
  115. LDST_SRCDST_BYTE_CONTEXT);
  116. if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
  117. /* Save K1 */
  118. append_fifo_store(desc, adata->key_dma, adata->keylen,
  119. LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
  120. }
  121. EXPORT_SYMBOL(cnstr_shdsc_sk_hash);
  122. MODULE_LICENSE("Dual BSD/GPL");
  123. MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
  124. MODULE_AUTHOR("NXP Semiconductors");