tegra-se-key.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  3. /*
  4. * Crypto driver file to manage keys of NVIDIA Security Engine.
  5. */
  6. #include <linux/bitops.h>
  7. #include <linux/module.h>
  8. #include <crypto/aes.h>
  9. #include "tegra-se.h"
  10. #define SE_KEY_FULL_MASK GENMASK(SE_MAX_KEYSLOT, 0)
  11. /* Reserve keyslot 0, 14, 15 */
  12. #define SE_KEY_RSVD_MASK (BIT(0) | BIT(14) | BIT(15))
  13. #define SE_KEY_VALID_MASK (SE_KEY_FULL_MASK & ~SE_KEY_RSVD_MASK)
  14. /* Mutex lock to guard keyslots */
  15. static DEFINE_MUTEX(kslt_lock);
  16. /* Keyslot bitmask (0 = available, 1 = in use/not available) */
  17. static u16 tegra_se_keyslots = SE_KEY_RSVD_MASK;
  18. static u16 tegra_keyslot_alloc(void)
  19. {
  20. u16 keyid;
  21. mutex_lock(&kslt_lock);
  22. /* Check if all key slots are full */
  23. if (tegra_se_keyslots == GENMASK(SE_MAX_KEYSLOT, 0)) {
  24. mutex_unlock(&kslt_lock);
  25. return 0;
  26. }
  27. keyid = ffz(tegra_se_keyslots);
  28. tegra_se_keyslots |= BIT(keyid);
  29. mutex_unlock(&kslt_lock);
  30. return keyid;
  31. }
  32. static void tegra_keyslot_free(u16 slot)
  33. {
  34. mutex_lock(&kslt_lock);
  35. tegra_se_keyslots &= ~(BIT(slot));
  36. mutex_unlock(&kslt_lock);
  37. }
  38. static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
  39. const u32 *key, u32 keylen, u16 slot, u32 alg)
  40. {
  41. int i = 0, j;
  42. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  43. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
  44. cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_DUMMY;
  45. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  46. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->manifest);
  47. cpuvaddr[i++] = se->manifest(se->owner, alg, keylen);
  48. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  49. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_dst);
  50. cpuvaddr[i++] = SE_AES_KEY_DST_INDEX(slot);
  51. for (j = 0; j < keylen / 4; j++) {
  52. /* Set key address */
  53. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  54. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_addr);
  55. cpuvaddr[i++] = j;
  56. /* Set key data */
  57. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  58. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_data);
  59. cpuvaddr[i++] = key[j];
  60. }
  61. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  62. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->config);
  63. cpuvaddr[i++] = SE_CFG_INS;
  64. cpuvaddr[i++] = host1x_opcode_setpayload(1);
  65. cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
  66. cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_START |
  67. SE_AES_OP_LASTBUF;
  68. cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
  69. cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
  70. host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
  71. dev_dbg(se->dev, "key-slot %u key-manifest %#x\n",
  72. slot, se->manifest(se->owner, alg, keylen));
  73. return i;
  74. }
  75. static bool tegra_key_in_kslt(u32 keyid)
  76. {
  77. bool ret;
  78. if (keyid > SE_MAX_KEYSLOT)
  79. return false;
  80. mutex_lock(&kslt_lock);
  81. ret = ((BIT(keyid) & SE_KEY_VALID_MASK) &&
  82. (BIT(keyid) & tegra_se_keyslots));
  83. mutex_unlock(&kslt_lock);
  84. return ret;
  85. }
  86. static int tegra_key_insert(struct tegra_se *se, const u8 *key,
  87. u32 keylen, u16 slot, u32 alg)
  88. {
  89. const u32 *keyval = (u32 *)key;
  90. u32 *addr = se->keybuf->addr, size;
  91. int ret;
  92. mutex_lock(&kslt_lock);
  93. size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg);
  94. ret = tegra_se_host1x_submit(se, se->keybuf, size);
  95. mutex_unlock(&kslt_lock);
  96. return ret;
  97. }
  98. void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
  99. {
  100. u8 zkey[AES_MAX_KEY_SIZE] = {0};
  101. if (!keyid)
  102. return;
  103. /* Overwrite the key with 0s */
  104. tegra_key_insert(se, zkey, AES_MAX_KEY_SIZE, keyid, alg);
  105. tegra_keyslot_free(keyid);
  106. }
  107. void tegra_key_invalidate_reserved(struct tegra_se *se, u32 keyid, u32 alg)
  108. {
  109. u8 zkey[AES_MAX_KEY_SIZE] = {0};
  110. if (!keyid)
  111. return;
  112. /* Overwrite the key with 0s */
  113. tegra_key_insert(se, zkey, AES_MAX_KEY_SIZE, keyid, alg);
  114. }
  115. inline int tegra_key_submit_reserved(struct tegra_se *se, const u8 *key,
  116. u32 keylen, u32 alg, u32 *keyid)
  117. {
  118. return tegra_key_insert(se, key, keylen, *keyid, alg);
  119. }
  120. int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u32 *keyid)
  121. {
  122. int ret;
  123. /* Use the existing slot if it is already allocated */
  124. if (!tegra_key_in_kslt(*keyid)) {
  125. *keyid = tegra_keyslot_alloc();
  126. if (!(*keyid)) {
  127. dev_dbg(se->dev, "failed to allocate key slot\n");
  128. return -ENOMEM;
  129. }
  130. }
  131. ret = tegra_key_insert(se, key, keylen, *keyid, alg);
  132. if (ret)
  133. return ret;
  134. return 0;
  135. }