fsl_caam_c.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. --- fsl_caam-orig.c 2022-10-21 15:50:35.709951000 -0700
  2. +++ fsl_caam.c 2022-12-28 06:30:34.788316189 -0800
  3. @@ -7872,3 +7872,462 @@
  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 lenght 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. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  132. + if (status == kStatus_Success) {
  133. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  134. + }
  135. +
  136. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  137. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  138. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  139. + DCACHE_InvalidateByRange((uint32_t)k, *sizeK);
  140. + DCACHE_InvalidateByRange((uint32_t)p, *sizeP);
  141. +#endif /* CAAM_OUT_INVALIDATE */
  142. + return status;
  143. +}
  144. +
  145. +
  146. +/*!
  147. + * brief generate ECC signature.
  148. + *
  149. + * This function creates an ECC signature.
  150. + *
  151. + * param base CAAM peripheral base address
  152. + * param[in] k private key
  153. + * param[in] sizeK holds size of input k in bytes.
  154. + * param[in] hash contains the hash to sign
  155. + * param[in] sizeHash is the size of 'hash' in bytes.
  156. + * param[out] sig signature output
  157. + * param[in,out] sizeSig pointer to size variable. On input it holds size of input sig in bytes. On output it holds size of
  158. + * of generated signature in bytes.
  159. + * param keyType type of ECC key i.e P256 / P384
  160. + * param enc option to use black key
  161. + * return Operation status.
  162. + */
  163. +status_t CAAM_ECC_Sign(CAAM_Type *base,
  164. + caam_handle_t *handle,
  165. + const uint8_t *k,
  166. + size_t sizeK,
  167. + const uint8_t *hash,
  168. + size_t sizeHash,
  169. + uint8_t *r,
  170. + size_t sizeR,
  171. + uint8_t *s,
  172. + size_t sizeS,
  173. + int keyType,
  174. + uint32_t enc)
  175. +{
  176. + size_t keySz = 0;
  177. + caam_desc_pkha_ecc_t descriptor;
  178. + status_t status = kStatus_InvalidArgument;
  179. + uint32_t descriptorSize = ARRAY_SIZE(templateSignECC);
  180. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateSignECC), caam_desc_pkha_ecc_t_size_too_low);
  181. +
  182. + /* check if known type of key encryption */
  183. + if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
  184. + return status;
  185. + }
  186. +
  187. + /* check is supported key type */
  188. + keySz = CheckSupportedKeyType(keyType);
  189. + if (keySz == 0) {
  190. + return status;
  191. + }
  192. +
  193. + /* sanity check on size of buffers passed in */
  194. + if (sizeR < keySz || sizeS < keySz) {
  195. + return status;
  196. + }
  197. +
  198. + /* initialize descriptor from template */
  199. + (void)caam_memcpy(descriptor, templateSignECC, sizeof(templateSignECC));
  200. +
  201. + /* add descriptor lenght in bytes to HEADER descriptor command */
  202. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  203. +
  204. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
  205. + DESC_SET_ADDR(descriptor[2], k);
  206. + DESC_SET_ADDR(descriptor[3], hash);
  207. + DESC_SET_ADDR(descriptor[4], r);
  208. + DESC_SET_ADDR(descriptor[5], s);
  209. + DESC_ADD_LEN(descriptor[6], sizeHash);
  210. +
  211. + /* add in if is encrypted */
  212. + descriptor[7] |= enc;
  213. +
  214. + /* schedule the job */
  215. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  216. + if (status == kStatus_Success) {
  217. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  218. + }
  219. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  220. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  221. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  222. + DCACHE_InvalidateByRange((uint32_t)r, sizeR);
  223. + DCACHE_InvalidateByRange((uint32_t)s, sizeS);
  224. +#endif /* CAAM_OUT_INVALIDATE */
  225. + return status;
  226. +}
  227. +
  228. +
  229. +/*!
  230. + * brief do an ECC verify.
  231. + *
  232. + * This function verifies an ECC signature.
  233. + *
  234. + * param base CAAM peripheral base address
  235. + * param[in] p public key
  236. + * param[in] sizeP pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
  237. + * of generated private key k in bytes.
  238. + * param[in] sig signature to verify
  239. + * param[in] sizeSig size of signature in bytes
  240. + * param[in] hash contains the hash to sign
  241. + * param[in] sizeHash is the size of 'hash' in bytes.
  242. + * param keyType type of ECC key i.e P256 / P384
  243. + * param enc option to use black key
  244. + * return Operation status.
  245. + */
  246. +status_t CAAM_ECC_Verify(CAAM_Type *base,
  247. + caam_handle_t *handle,
  248. + const uint8_t *p,
  249. + size_t sizeP,
  250. + const uint8_t *r,
  251. + size_t sizeR,
  252. + const uint8_t *s,
  253. + size_t sizeS,
  254. + const uint8_t *hash,
  255. + size_t sizeHash,
  256. + int keyType)
  257. +{
  258. + size_t keySz = 0;
  259. + caam_desc_pkha_ecc_t descriptor;
  260. + status_t status = kStatus_InvalidArgument;
  261. + uint8_t tmp[256];
  262. + uint32_t descriptorSize = ARRAY_SIZE(templateVerifyECC);
  263. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateVerifyECC), caam_desc_pkha_ecc_t_size_too_low);
  264. +
  265. + /* check is supported key type */
  266. + keySz = CheckSupportedKeyType(keyType);
  267. + if (keySz == 0 || sizeR < keySz || sizeS < keySz) {
  268. + return status;
  269. + }
  270. +
  271. + /* initialize descriptor from template */
  272. + (void)caam_memcpy(descriptor, templateVerifyECC, sizeof(templateVerifyECC));
  273. +
  274. + /* add descriptor lenght in bytes to HEADER descriptor command */
  275. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  276. +
  277. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
  278. + DESC_SET_ADDR(descriptor[2], p);
  279. + DESC_SET_ADDR(descriptor[3], hash);
  280. + DESC_SET_ADDR(descriptor[4], r);
  281. + DESC_SET_ADDR(descriptor[5], s);
  282. + DESC_SET_ADDR(descriptor[6], tmp);
  283. + DESC_ADD_LEN(descriptor[7], sizeHash);
  284. +
  285. + /* schedule the job */
  286. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  287. + if (status == kStatus_Success) {
  288. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  289. + }
  290. + return status;
  291. +}
  292. +
  293. +
  294. +/*!
  295. + * brief generate ECC shared secret.
  296. + *
  297. + * This function creates an ECC shared secret.
  298. + *
  299. + * param base CAAM peripheral base address
  300. + * param[in] k private key
  301. + * param[in] sizeK holds size of input k in bytes.
  302. + * param[in] pub contains the public key (x,y)
  303. + * param[in] sizePub is the size of 'pub' in bytes.
  304. + * param[out] out output buffer to hold shared secret
  305. + * param[in] sizeOut size of out buffer
  306. + * param keyType type of ECC key i.e P256 / P384
  307. + * param enc option to use black key
  308. + * return Operation status.
  309. + */
  310. +status_t CAAM_ECC_ECDH(CAAM_Type *base,
  311. + caam_handle_t *handle,
  312. + const uint8_t *k,
  313. + size_t sizeK,
  314. + const uint8_t *pub,
  315. + size_t sizePub,
  316. + uint8_t *out,
  317. + size_t sizeOut,
  318. + int keyType,
  319. + uint32_t enc)
  320. +{
  321. + size_t keySz = 0;
  322. + caam_desc_pkha_ecc_t descriptor;
  323. + status_t status = kStatus_InvalidArgument;
  324. + uint32_t descriptorSize = ARRAY_SIZE(templateAgreeECC);
  325. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateAgreeECC), caam_desc_pkha_ecc_t_size_too_low);
  326. +
  327. + /* check if known type of key encryption */
  328. + if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
  329. + return status;
  330. + }
  331. +
  332. + /* check is supported key type */
  333. + keySz = CheckSupportedKeyType(keyType);
  334. + if (keySz == 0 || sizeK > keySz || sizeOut != keySz) {
  335. + return status;
  336. + }
  337. +
  338. + /* initialize descriptor from template */
  339. + (void)caam_memcpy(descriptor, templateAgreeECC, sizeof(templateAgreeECC));
  340. +
  341. + /* add descriptor lenght in bytes to HEADER descriptor command */
  342. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  343. +
  344. + DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_KEYGEN_PD | keyType));
  345. + DESC_SET_ADDR(descriptor[2], pub);
  346. + DESC_SET_ADDR(descriptor[3], k);
  347. + DESC_SET_ADDR(descriptor[4], out);
  348. +
  349. + /* add in if is encrypted */
  350. + descriptor[5] |= enc;
  351. +
  352. + /* schedule the job */
  353. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  354. + if (status == kStatus_Success) {
  355. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  356. + }
  357. +
  358. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  359. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  360. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  361. + DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
  362. +#endif /* CAAM_OUT_INVALIDATE */
  363. + return status;
  364. +}
  365. +
  366. +
  367. +/* Handle BLOB create and open */
  368. +static const uint32_t templateBlob[] = {
  369. + /* 00 */ 0xB0800000u, /* HEADER */
  370. + /* 01 */ 0x14400000u, /* class */
  371. + /* 02 */ 0x00000000u, /* key mod */
  372. + /* 03 */ 0xF0000000u, /* SEQ input size */
  373. + /* 04 */ 0x00000000u, /* input */
  374. + /* 05 */ 0xF8000000u, /* SEQ output size */
  375. + /* 06 */ 0x00000000u, /* output */
  376. + /* 07 */ 0x800D0000u, /* Operation */
  377. +};
  378. +
  379. +
  380. +/*!
  381. + * brief generate ECC Keypair.
  382. + *
  383. + * This function generates ECC private/public key pair.
  384. + *
  385. + * param base CAAM peripheral base address
  386. + * param[out] k private key
  387. + * param[in,out] sizeK pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
  388. + * of generated private key k in bytes.
  389. + * param[out] p public key
  390. + * param[in,out] sizeP pointer to size variable. On input it holds size of input p in bytes. On output it holds size of
  391. + * of generated public key p in bytes.
  392. + * param keyType type of ECC key, i.e P256 / P384
  393. + * param enc option to create black key
  394. + * return Operation status.
  395. + */
  396. +status_t CAAM_Blob(CAAM_Type *base,
  397. + caam_handle_t *handle,
  398. + uint8_t *in,
  399. + size_t sizeIn,
  400. + uint8_t *out,
  401. + size_t sizeOut,
  402. + uint8_t *keyMod,
  403. + size_t keyModSz,
  404. + uint32_t dir,
  405. + uint32_t color)
  406. +{
  407. + caam_desc_pkha_ecc_t descriptor;
  408. + status_t status = kStatus_InvalidArgument;
  409. + uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
  410. + BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateBlob), caam_desc_pkha_ecc_t_size_too_low);
  411. +
  412. + /* check if known type of key encryption */
  413. + if (color != CAAM_RED_BLOB && color != CAAM_BLACK_BLOB) {
  414. + return status;
  415. + }
  416. +
  417. + if (dir != CAAM_ENCAP_BLOB && dir != CAAM_DECAP_BLOB) {
  418. + return status;
  419. + }
  420. +
  421. + /* simple sanity check on output size to avoid invalidating more
  422. + * than wanted */
  423. + if (dir == CAAM_ENCAP_BLOB &&
  424. + (sizeOut > sizeIn + CAAM_PADDING_SIZE_BLOB)) {
  425. + return status;
  426. + }
  427. +
  428. + if (dir == CAAM_DECAP_BLOB &&
  429. + (sizeOut > sizeIn - CAAM_PADDING_SIZE_BLOB)) {
  430. + return status;
  431. + }
  432. +
  433. + /* initialize descriptor from template */
  434. + (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
  435. +
  436. + /* add descriptor lenght in bytes to HEADER descriptor command */
  437. + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
  438. + descriptor[1] |= color; /* add color of blob */
  439. + DESC_SET_ADDR(descriptor[2], keyMod);
  440. + DESC_ADD_LEN(descriptor[3], sizeIn);
  441. + DESC_SET_ADDR(descriptor[4], in);
  442. + DESC_ADD_LEN(descriptor[5], sizeOut);
  443. + DESC_SET_ADDR(descriptor[6], out);
  444. + descriptor[7] |= dir; /* add in direction of blob (encap / decap) */
  445. +
  446. + /* set black key flag */
  447. + if (color == CAAM_BLACK_BLOB) {
  448. + descriptor[7] |= 0x4; /* ECB black key */
  449. + /* additionally AES-CCM would have EXT (bit 8) hot */
  450. + }
  451. +
  452. + /* schedule the job */
  453. + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
  454. + if (status == kStatus_Success) {
  455. + status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
  456. + }
  457. +
  458. +#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
  459. + /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
  460. + /* Invalidate unaligned data can cause memory corruption in write-back mode */
  461. + DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
  462. +#endif /* CAAM_OUT_INVALIDATE */
  463. + return status;
  464. +}
  465. +