fsl_caam_c.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. --- fsl_caam.c 2023-01-12 23:39:04.000000000 -0800
  2. +++ fsl_caam-expanded.c 2023-06-23 00:18:14.395128903 -0700
  3. @@ -7872,3 +7872,476 @@
  4. }
  5. return status;
  6. }
  7. +
  8. +
  9. +#define CAAM_ECDSA_PD 0x00400000
  10. +#define CAAM_ECDSA_KEYGEN_PD 0x02000000
  11. +
  12. +static const uint32_t templateKeyPairECC[] = {
  13. + /* 00 */ 0xB0840000u, /* HEADER */
  14. + /* 01 */ 0x00000000u, /* ECDSEL */
  15. + /* 02 */ 0x00000000u, /* Private Key Address */
  16. + /* 03 */ 0x00000000u, /* Public Key Address */
  17. + /* 04 */ 0x80140002u, /* Operation */
  18. +};
  19. +
  20. +
  21. +static const uint32_t templateSignECC[] = {
  22. + /* 00 */ 0xB0870000u, /* HEADER */
  23. + /* 01 */ 0x00000000u, /* ECDSEL */
  24. + /* 02 */ 0x00000000u, /* Private Key Address */
  25. + /* 03 */ 0x00000000u, /* Message Address */
  26. + /* 04 */ 0x00000000u, /* R of signature */
  27. + /* 05 */ 0x00000000u, /* S of signature */
  28. + /* 06 */ 0x00000000u, /* Message Size */
  29. + /* 07 */ 0x80150802u, /* Operation */
  30. +};
  31. +
  32. +
  33. +static const uint32_t templateVerifyECC[] = {
  34. + /* 00 */ 0xB0880000u, /* HEADER */
  35. + /* 01 */ 0x00000000u, /* ECDSEL */
  36. + /* 02 */ 0x00000000u, /* Public Key Address (X,Y) */
  37. + /* 03 */ 0x00000000u, /* Message Address */
  38. + /* 04 */ 0x00000000u, /* R of signature */
  39. + /* 05 */ 0x00000000u, /* S of signature */
  40. + /* 06 */ 0x00000000u, /* tmp buffer */
  41. + /* 07 */ 0x00000000u, /* Message Size */
  42. + /* 08 */ 0x80160802u, /* Operation */
  43. +};
  44. +
  45. +
  46. +static const uint32_t templateAgreeECC[] = {
  47. + /* 00 */ 0xB0850000u, /* HEADER */
  48. + /* 01 */ 0x00000000u, /* ECDSEL */
  49. + /* 02 */ 0x00000000u, /* Public Key Address */
  50. + /* 03 */ 0x00000000u, /* Private Key Address */
  51. + /* 04 */ 0x00000000u, /* Shared Output */
  52. + /* 07 */ 0x80170002u, /* Operation */
  53. +};
  54. +
  55. +
  56. +static int CheckSupportedKeyType(int keyType)
  57. +{
  58. + int ret = 0;
  59. +
  60. + switch (keyType) {
  61. + case CAAM_ECDSA_P256:
  62. + ret = 32;
  63. + break;
  64. +
  65. + case CAAM_ECDSA_P384:
  66. + ret = 48;
  67. + break;
  68. +
  69. + case CAAM_ECDSA_P521:
  70. + ret = 66;
  71. + break;
  72. + }
  73. + return ret;
  74. +}
  75. +
  76. +
  77. +/*!
  78. + * brief generate ECC Keypair.
  79. + *
  80. + * This function generates ECC private/public key pair.
  81. + *
  82. + * param base CAAM peripheral base address
  83. + * param[out] k private key
  84. + * param[in,out] sizeK pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
  85. + * of generated private key k in bytes.
  86. + * param[out] p public key
  87. + * param[in,out] sizeP pointer to size variable. On input it holds size of input p in bytes. On output it holds size of
  88. + * of generated public key p in bytes.
  89. + * param keyType type of ECC key, i.e P256 / P384
  90. + * param enc option to create black key
  91. + * return Operation status.
  92. + */
  93. +status_t CAAM_ECC_Keygen(CAAM_Type *base,
  94. + caam_handle_t *handle,
  95. + uint8_t *k,
  96. + size_t *sizeK,
  97. + uint8_t *p,
  98. + size_t *sizeP,
  99. + int keyType,
  100. + uint32_t enc)
  101. +{
  102. + caam_desc_pkha_ecc_t descriptor;
  103. + status_t status = kStatus_InvalidArgument;
  104. + uint32_t descriptorSize = ARRAY_SIZE(templateKeyPairECC);
  105. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateKeyPairECC), caam_desc_pkha_ecc_t_size_too_low);
  106. +
  107. + /* check if known type of key encryption */
  108. + if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
  109. + return status;
  110. + }
  111. +
  112. + /* check is supported key type */
  113. + if (CheckSupportedKeyType(keyType) == 0) {
  114. + return status;
  115. + }
  116. +
  117. + /* initialize descriptor from template */
  118. + (void)caam_memcpy(descriptor, templateKeyPairECC, sizeof(templateKeyPairECC));
  119. +
  120. + /* add descriptor length in bytes to HEADER descriptor command */
  121. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  122. +
  123. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_KEYGEN_PD | keyType));
  124. + DESC_SET_ADDR(descriptor[2], k);
  125. + DESC_SET_ADDR(descriptor[3], p);
  126. +
  127. + /* add in if is encrypted */
  128. + descriptor[4] |= enc;
  129. +
  130. + /* schedule the job */
  131. + do {
  132. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  133. + } while (status == kStatus_CAAM_Again);
  134. + if (status == kStatus_Success) {
  135. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  136. + }
  137. +
  138. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  139. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  140. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  141. + DCACHE_InvalidateByRange((uint32_t)k, *sizeK);
  142. + DCACHE_InvalidateByRange((uint32_t)p, *sizeP);
  143. +#endif /* CAAM_OUT_INVALIDATE */
  144. + return status;
  145. +}
  146. +
  147. +
  148. +/*!
  149. + * brief generate ECC signature.
  150. + *
  151. + * This function creates an ECC signature.
  152. + *
  153. + * param base CAAM peripheral base address
  154. + * param[in] k private key
  155. + * param[in] sizeK holds size of input k in bytes.
  156. + * param[in] hash contains the hash to sign
  157. + * param[in] sizeHash is the size of 'hash' in bytes.
  158. + * param[out] sig signature output
  159. + * param[in,out] sizeSig pointer to size variable. On input it holds size of input sig in bytes. On output it holds size of
  160. + * of generated signature in bytes.
  161. + * param keyType type of ECC key i.e P256 / P384
  162. + * param enc option to use black key
  163. + * return Operation status.
  164. + */
  165. +status_t CAAM_ECC_Sign(CAAM_Type *base,
  166. + caam_handle_t *handle,
  167. + const uint8_t *k,
  168. + size_t sizeK,
  169. + const uint8_t *hash,
  170. + size_t sizeHash,
  171. + uint8_t *r,
  172. + size_t sizeR,
  173. + uint8_t *s,
  174. + size_t sizeS,
  175. + int keyType,
  176. + uint32_t enc)
  177. +{
  178. + size_t keySz = 0;
  179. + caam_desc_pkha_ecc_t descriptor;
  180. + status_t status = kStatus_InvalidArgument;
  181. + uint32_t descriptorSize = ARRAY_SIZE(templateSignECC);
  182. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateSignECC), caam_desc_pkha_ecc_t_size_too_low);
  183. +
  184. + /* check if known type of key encryption */
  185. + if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
  186. + return status;
  187. + }
  188. +
  189. + /* check is supported key type */
  190. + keySz = CheckSupportedKeyType(keyType);
  191. + if (keySz == 0) {
  192. + return status;
  193. + }
  194. +
  195. + /* sanity check on size of buffers passed in */
  196. + if (sizeR < keySz || sizeS < keySz) {
  197. + return status;
  198. + }
  199. +
  200. + /* initialize descriptor from template */
  201. + (void)caam_memcpy(descriptor, templateSignECC, sizeof(templateSignECC));
  202. +
  203. + /* add descriptor length in bytes to HEADER descriptor command */
  204. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  205. +
  206. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
  207. + DESC_SET_ADDR(descriptor[2], k);
  208. + DESC_SET_ADDR(descriptor[3], hash);
  209. + DESC_SET_ADDR(descriptor[4], r);
  210. + DESC_SET_ADDR(descriptor[5], s);
  211. + DESC_ADD_LEN(descriptor[6], sizeHash);
  212. +
  213. + /* add in if is encrypted */
  214. + descriptor[7] |= enc;
  215. +
  216. + /* schedule the job */
  217. + do {
  218. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  219. + } while (status == kStatus_CAAM_Again);
  220. + if (status == kStatus_Success) {
  221. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  222. + }
  223. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  224. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  225. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  226. + DCACHE_InvalidateByRange((uint32_t)r, sizeR);
  227. + DCACHE_InvalidateByRange((uint32_t)s, sizeS);
  228. +#endif /* CAAM_OUT_INVALIDATE */
  229. + return status;
  230. +}
  231. +
  232. +
  233. +/*!
  234. + * brief do an ECC verify.
  235. + *
  236. + * This function verifies an ECC signature.
  237. + *
  238. + * param base CAAM peripheral base address
  239. + * param[in] p public key
  240. + * param[in] sizeP pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
  241. + * of generated private key k in bytes.
  242. + * param[in] sig signature to verify
  243. + * param[in] sizeSig size of signature in bytes
  244. + * param[in] hash contains the hash to sign
  245. + * param[in] sizeHash is the size of 'hash' in bytes.
  246. + * param keyType type of ECC key i.e P256 / P384
  247. + * param enc option to use black key
  248. + * return Operation status.
  249. + */
  250. +status_t CAAM_ECC_Verify(CAAM_Type *base,
  251. + caam_handle_t *handle,
  252. + const uint8_t *p,
  253. + size_t sizeP,
  254. + const uint8_t *r,
  255. + size_t sizeR,
  256. + const uint8_t *s,
  257. + size_t sizeS,
  258. + const uint8_t *hash,
  259. + size_t sizeHash,
  260. + int keyType)
  261. +{
  262. + size_t keySz = 0;
  263. + caam_desc_pkha_ecc_t descriptor;
  264. + status_t status = kStatus_InvalidArgument;
  265. + uint8_t tmp[256];
  266. + uint32_t descriptorSize = ARRAY_SIZE(templateVerifyECC);
  267. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateVerifyECC), caam_desc_pkha_ecc_t_size_too_low);
  268. +
  269. + /* check is supported key type */
  270. + keySz = CheckSupportedKeyType(keyType);
  271. + if (keySz == 0 || sizeR < keySz || sizeS < keySz) {
  272. + return status;
  273. + }
  274. +
  275. + /* initialize descriptor from template */
  276. + (void)caam_memcpy(descriptor, templateVerifyECC, sizeof(templateVerifyECC));
  277. +
  278. + /* add descriptor length in bytes to HEADER descriptor command */
  279. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  280. +
  281. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
  282. + DESC_SET_ADDR(descriptor[2], p);
  283. + DESC_SET_ADDR(descriptor[3], hash);
  284. + DESC_SET_ADDR(descriptor[4], r);
  285. + DESC_SET_ADDR(descriptor[5], s);
  286. + DESC_SET_ADDR(descriptor[6], tmp);
  287. + DESC_ADD_LEN(descriptor[7], sizeHash);
  288. +
  289. + /* schedule the job */
  290. + do {
  291. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  292. + } while (status == kStatus_CAAM_Again);
  293. + if (status == kStatus_Success) {
  294. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  295. + }
  296. + return status;
  297. +}
  298. +
  299. +
  300. +/*!
  301. + * brief generate ECC shared secret.
  302. + *
  303. + * This function creates an ECC shared secret.
  304. + *
  305. + * param base CAAM peripheral base address
  306. + * param[in] k private key
  307. + * param[in] sizeK holds size of input k in bytes.
  308. + * param[in] pub contains the public key (x,y)
  309. + * param[in] sizePub is the size of 'pub' in bytes.
  310. + * param[out] out output buffer to hold shared secret
  311. + * param[in] sizeOut size of out buffer
  312. + * param keyType type of ECC key i.e P256 / P384
  313. + * param enc option to use black key
  314. + * return Operation status.
  315. + */
  316. +status_t CAAM_ECC_ECDH(CAAM_Type *base,
  317. + caam_handle_t *handle,
  318. + const uint8_t *k,
  319. + size_t sizeK,
  320. + const uint8_t *pub,
  321. + size_t sizePub,
  322. + uint8_t *out,
  323. + size_t sizeOut,
  324. + int keyType,
  325. + uint32_t enc)
  326. +{
  327. + size_t keySz = 0;
  328. + caam_desc_pkha_ecc_t descriptor;
  329. + status_t status = kStatus_InvalidArgument;
  330. + uint32_t descriptorSize = ARRAY_SIZE(templateAgreeECC);
  331. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateAgreeECC), caam_desc_pkha_ecc_t_size_too_low);
  332. +
  333. + /* check if known type of key encryption */
  334. + if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
  335. + return status;
  336. + }
  337. +
  338. + /* check is supported key type */
  339. + keySz = CheckSupportedKeyType(keyType);
  340. + if (keySz == 0 || sizeK > keySz || sizeOut != keySz) {
  341. + return status;
  342. + }
  343. +
  344. + /* initialize descriptor from template */
  345. + (void)caam_memcpy(descriptor, templateAgreeECC, sizeof(templateAgreeECC));
  346. +
  347. + /* add descriptor length in bytes to HEADER descriptor command */
  348. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  349. +
  350. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_KEYGEN_PD | keyType));
  351. + DESC_SET_ADDR(descriptor[2], pub);
  352. + DESC_SET_ADDR(descriptor[3], k);
  353. + DESC_SET_ADDR(descriptor[4], out);
  354. +
  355. + /* add in if is encrypted */
  356. + descriptor[5] |= enc;
  357. +
  358. + /* schedule the job */
  359. + do {
  360. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  361. + } while (status == kStatus_CAAM_Again);
  362. + if (status == kStatus_Success) {
  363. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  364. + }
  365. +
  366. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  367. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  368. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  369. + DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
  370. +#endif /* CAAM_OUT_INVALIDATE */
  371. + return status;
  372. +}
  373. +
  374. +
  375. +/* Handle BLOB create and open */
  376. +static const uint32_t templateBlob[] = {
  377. + /* 00 */ 0xB0800000u, /* HEADER */
  378. + /* 01 */ 0x04000000u, /* class */
  379. + /* 02 */ 0x00000000u, /* key mod */
  380. + /* 03 */ 0xF0000000u, /* SEQ input size */
  381. + /* 04 */ 0x00000000u, /* input */
  382. + /* 05 */ 0xF8000000u, /* SEQ output size */
  383. + /* 06 */ 0x00000000u, /* output */
  384. + /* 07 */ 0x800D0000u, /* Operation */
  385. +};
  386. +
  387. +
  388. +/*!
  389. + * brief generate ECC Keypair.
  390. + *
  391. + * This function generates ECC private/public key pair.
  392. + *
  393. + * param base CAAM peripheral base address
  394. + * param[out] k private key
  395. + * param[in,out] sizeK pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
  396. + * of generated private key k in bytes.
  397. + * param[out] p public key
  398. + * param[in,out] sizeP pointer to size variable. On input it holds size of input p in bytes. On output it holds size of
  399. + * of generated public key p in bytes.
  400. + * param keyType type of ECC key, i.e P256 / P384
  401. + * param enc option to create black key
  402. + * return Operation status.
  403. + */
  404. +status_t CAAM_Blob(CAAM_Type *base,
  405. + caam_handle_t *handle,
  406. + uint8_t *in,
  407. + size_t sizeIn,
  408. + uint8_t *out,
  409. + size_t sizeOut,
  410. + uint8_t *keyMod,
  411. + size_t keyModSz,
  412. + uint32_t dir,
  413. + uint32_t color)
  414. +{
  415. + caam_desc_pkha_ecc_t descriptor;
  416. + status_t status = kStatus_InvalidArgument;
  417. + uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
  418. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateBlob), caam_desc_pkha_ecc_t_size_too_low);
  419. +
  420. + /* check if known type of key encryption */
  421. + if (color != CAAM_RED_BLOB && color != CAAM_BLACK_BLOB) {
  422. + return status;
  423. + }
  424. +
  425. + if (dir != CAAM_ENCAP_BLOB && dir != CAAM_DECAP_BLOB) {
  426. + return status;
  427. + }
  428. +
  429. + /* simple sanity check on output size to avoid invalidating more
  430. + * than wanted */
  431. + if (dir == CAAM_ENCAP_BLOB &&
  432. + (sizeOut > sizeIn + CAAM_PADDING_SIZE_BLOB)) {
  433. + return status;
  434. + }
  435. +
  436. + if (keyModSz != CAAM_SM_KEYMODSZ && keyModSz != CAAM_KEYMODSZ) {
  437. + return status;
  438. + }
  439. +
  440. + if (dir == CAAM_DECAP_BLOB &&
  441. + (sizeOut > sizeIn - CAAM_PADDING_SIZE_BLOB)) {
  442. + return status;
  443. + }
  444. +
  445. + /* initialize descriptor from template */
  446. + (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
  447. +
  448. + /* add descriptor length in bytes to HEADER descriptor command */
  449. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  450. + descriptor[1] |= keyModSz;
  451. + DESC_SET_ADDR(descriptor[2], keyMod);
  452. + DESC_ADD_LEN(descriptor[3], sizeIn);
  453. + DESC_SET_ADDR(descriptor[4], in);
  454. + DESC_ADD_LEN(descriptor[5], sizeOut);
  455. + DESC_SET_ADDR(descriptor[6], out);
  456. + descriptor[7] |= dir; /* add in direction of blob (encap / decap) */
  457. +
  458. + /* set black key flag */
  459. + if (color == CAAM_BLACK_BLOB) {
  460. + descriptor[7] |= 0x4; /* ECB black key */
  461. + /* additionally AES-CCM would have EXT (bit 8) hot */
  462. + }
  463. +
  464. + /* schedule the job */
  465. + do {
  466. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  467. + } while (status == kStatus_CAAM_Again);
  468. + if (status == kStatus_Success) {
  469. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  470. + }
  471. +
  472. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  473. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  474. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  475. + DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
  476. +#endif /* CAAM_OUT_INVALIDATE */
  477. + return status;
  478. +}
  479. +