wolfssl-w32/IDE/MCUEXPRESSO/RT1170/fsl_caam_c.patch

480 lines
17 KiB
Diff

--- fsl_caam.c 2023-01-12 23:39:04.000000000 -0800
+++ fsl_caam-expanded.c 2023-06-23 00:18:14.395128903 -0700
@@ -7872,3 +7872,476 @@
}
return status;
}
+
+
+#define CAAM_ECDSA_PD 0x00400000
+#define CAAM_ECDSA_KEYGEN_PD 0x02000000
+
+static const uint32_t templateKeyPairECC[] = {
+ /* 00 */ 0xB0840000u, /* HEADER */
+ /* 01 */ 0x00000000u, /* ECDSEL */
+ /* 02 */ 0x00000000u, /* Private Key Address */
+ /* 03 */ 0x00000000u, /* Public Key Address */
+ /* 04 */ 0x80140002u, /* Operation */
+};
+
+
+static const uint32_t templateSignECC[] = {
+ /* 00 */ 0xB0870000u, /* HEADER */
+ /* 01 */ 0x00000000u, /* ECDSEL */
+ /* 02 */ 0x00000000u, /* Private Key Address */
+ /* 03 */ 0x00000000u, /* Message Address */
+ /* 04 */ 0x00000000u, /* R of signature */
+ /* 05 */ 0x00000000u, /* S of signature */
+ /* 06 */ 0x00000000u, /* Message Size */
+ /* 07 */ 0x80150802u, /* Operation */
+};
+
+
+static const uint32_t templateVerifyECC[] = {
+ /* 00 */ 0xB0880000u, /* HEADER */
+ /* 01 */ 0x00000000u, /* ECDSEL */
+ /* 02 */ 0x00000000u, /* Public Key Address (X,Y) */
+ /* 03 */ 0x00000000u, /* Message Address */
+ /* 04 */ 0x00000000u, /* R of signature */
+ /* 05 */ 0x00000000u, /* S of signature */
+ /* 06 */ 0x00000000u, /* tmp buffer */
+ /* 07 */ 0x00000000u, /* Message Size */
+ /* 08 */ 0x80160802u, /* Operation */
+};
+
+
+static const uint32_t templateAgreeECC[] = {
+ /* 00 */ 0xB0850000u, /* HEADER */
+ /* 01 */ 0x00000000u, /* ECDSEL */
+ /* 02 */ 0x00000000u, /* Public Key Address */
+ /* 03 */ 0x00000000u, /* Private Key Address */
+ /* 04 */ 0x00000000u, /* Shared Output */
+ /* 07 */ 0x80170002u, /* Operation */
+};
+
+
+static int CheckSupportedKeyType(int keyType)
+{
+ int ret = 0;
+
+ switch (keyType) {
+ case CAAM_ECDSA_P256:
+ ret = 32;
+ break;
+
+ case CAAM_ECDSA_P384:
+ ret = 48;
+ break;
+
+ case CAAM_ECDSA_P521:
+ ret = 66;
+ break;
+ }
+ return ret;
+}
+
+
+/*!
+ * brief generate ECC Keypair.
+ *
+ * This function generates ECC private/public key pair.
+ *
+ * param base CAAM peripheral base address
+ * param[out] k private key
+ * param[in,out] sizeK pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
+ * of generated private key k in bytes.
+ * param[out] p public key
+ * param[in,out] sizeP pointer to size variable. On input it holds size of input p in bytes. On output it holds size of
+ * of generated public key p in bytes.
+ * param keyType type of ECC key, i.e P256 / P384
+ * param enc option to create black key
+ * return Operation status.
+ */
+status_t CAAM_ECC_Keygen(CAAM_Type *base,
+ caam_handle_t *handle,
+ uint8_t *k,
+ size_t *sizeK,
+ uint8_t *p,
+ size_t *sizeP,
+ int keyType,
+ uint32_t enc)
+{
+ caam_desc_pkha_ecc_t descriptor;
+ status_t status = kStatus_InvalidArgument;
+ uint32_t descriptorSize = ARRAY_SIZE(templateKeyPairECC);
+ BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateKeyPairECC), caam_desc_pkha_ecc_t_size_too_low);
+
+ /* check if known type of key encryption */
+ if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
+ return status;
+ }
+
+ /* check is supported key type */
+ if (CheckSupportedKeyType(keyType) == 0) {
+ return status;
+ }
+
+ /* initialize descriptor from template */
+ (void)caam_memcpy(descriptor, templateKeyPairECC, sizeof(templateKeyPairECC));
+
+ /* add descriptor length in bytes to HEADER descriptor command */
+ DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
+
+ DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_KEYGEN_PD | keyType));
+ DESC_SET_ADDR(descriptor[2], k);
+ DESC_SET_ADDR(descriptor[3], p);
+
+ /* add in if is encrypted */
+ descriptor[4] |= enc;
+
+ /* schedule the job */
+ do {
+ status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
+ } while (status == kStatus_CAAM_Again);
+ if (status == kStatus_Success) {
+ status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
+ }
+
+#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
+ /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
+ /* Invalidate unaligned data can cause memory corruption in write-back mode */
+ DCACHE_InvalidateByRange((uint32_t)k, *sizeK);
+ DCACHE_InvalidateByRange((uint32_t)p, *sizeP);
+#endif /* CAAM_OUT_INVALIDATE */
+ return status;
+}
+
+
+/*!
+ * brief generate ECC signature.
+ *
+ * This function creates an ECC signature.
+ *
+ * param base CAAM peripheral base address
+ * param[in] k private key
+ * param[in] sizeK holds size of input k in bytes.
+ * param[in] hash contains the hash to sign
+ * param[in] sizeHash is the size of 'hash' in bytes.
+ * param[out] sig signature output
+ * param[in,out] sizeSig pointer to size variable. On input it holds size of input sig in bytes. On output it holds size of
+ * of generated signature in bytes.
+ * param keyType type of ECC key i.e P256 / P384
+ * param enc option to use black key
+ * return Operation status.
+ */
+status_t CAAM_ECC_Sign(CAAM_Type *base,
+ caam_handle_t *handle,
+ const uint8_t *k,
+ size_t sizeK,
+ const uint8_t *hash,
+ size_t sizeHash,
+ uint8_t *r,
+ size_t sizeR,
+ uint8_t *s,
+ size_t sizeS,
+ int keyType,
+ uint32_t enc)
+{
+ size_t keySz = 0;
+ caam_desc_pkha_ecc_t descriptor;
+ status_t status = kStatus_InvalidArgument;
+ uint32_t descriptorSize = ARRAY_SIZE(templateSignECC);
+ BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateSignECC), caam_desc_pkha_ecc_t_size_too_low);
+
+ /* check if known type of key encryption */
+ if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
+ return status;
+ }
+
+ /* check is supported key type */
+ keySz = CheckSupportedKeyType(keyType);
+ if (keySz == 0) {
+ return status;
+ }
+
+ /* sanity check on size of buffers passed in */
+ if (sizeR < keySz || sizeS < keySz) {
+ return status;
+ }
+
+ /* initialize descriptor from template */
+ (void)caam_memcpy(descriptor, templateSignECC, sizeof(templateSignECC));
+
+ /* add descriptor length in bytes to HEADER descriptor command */
+ DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
+
+ DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
+ DESC_SET_ADDR(descriptor[2], k);
+ DESC_SET_ADDR(descriptor[3], hash);
+ DESC_SET_ADDR(descriptor[4], r);
+ DESC_SET_ADDR(descriptor[5], s);
+ DESC_ADD_LEN(descriptor[6], sizeHash);
+
+ /* add in if is encrypted */
+ descriptor[7] |= enc;
+
+ /* schedule the job */
+ do {
+ status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
+ } while (status == kStatus_CAAM_Again);
+ if (status == kStatus_Success) {
+ status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
+ }
+#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
+ /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
+ /* Invalidate unaligned data can cause memory corruption in write-back mode */
+ DCACHE_InvalidateByRange((uint32_t)r, sizeR);
+ DCACHE_InvalidateByRange((uint32_t)s, sizeS);
+#endif /* CAAM_OUT_INVALIDATE */
+ return status;
+}
+
+
+/*!
+ * brief do an ECC verify.
+ *
+ * This function verifies an ECC signature.
+ *
+ * param base CAAM peripheral base address
+ * param[in] p public key
+ * param[in] sizeP pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
+ * of generated private key k in bytes.
+ * param[in] sig signature to verify
+ * param[in] sizeSig size of signature in bytes
+ * param[in] hash contains the hash to sign
+ * param[in] sizeHash is the size of 'hash' in bytes.
+ * param keyType type of ECC key i.e P256 / P384
+ * param enc option to use black key
+ * return Operation status.
+ */
+status_t CAAM_ECC_Verify(CAAM_Type *base,
+ caam_handle_t *handle,
+ const uint8_t *p,
+ size_t sizeP,
+ const uint8_t *r,
+ size_t sizeR,
+ const uint8_t *s,
+ size_t sizeS,
+ const uint8_t *hash,
+ size_t sizeHash,
+ int keyType)
+{
+ size_t keySz = 0;
+ caam_desc_pkha_ecc_t descriptor;
+ status_t status = kStatus_InvalidArgument;
+ uint8_t tmp[256];
+ uint32_t descriptorSize = ARRAY_SIZE(templateVerifyECC);
+ BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateVerifyECC), caam_desc_pkha_ecc_t_size_too_low);
+
+ /* check is supported key type */
+ keySz = CheckSupportedKeyType(keyType);
+ if (keySz == 0 || sizeR < keySz || sizeS < keySz) {
+ return status;
+ }
+
+ /* initialize descriptor from template */
+ (void)caam_memcpy(descriptor, templateVerifyECC, sizeof(templateVerifyECC));
+
+ /* add descriptor length in bytes to HEADER descriptor command */
+ DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
+
+ DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_PD | keyType));
+ DESC_SET_ADDR(descriptor[2], p);
+ DESC_SET_ADDR(descriptor[3], hash);
+ DESC_SET_ADDR(descriptor[4], r);
+ DESC_SET_ADDR(descriptor[5], s);
+ DESC_SET_ADDR(descriptor[6], tmp);
+ DESC_ADD_LEN(descriptor[7], sizeHash);
+
+ /* schedule the job */
+ do {
+ status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
+ } while (status == kStatus_CAAM_Again);
+ if (status == kStatus_Success) {
+ status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
+ }
+ return status;
+}
+
+
+/*!
+ * brief generate ECC shared secret.
+ *
+ * This function creates an ECC shared secret.
+ *
+ * param base CAAM peripheral base address
+ * param[in] k private key
+ * param[in] sizeK holds size of input k in bytes.
+ * param[in] pub contains the public key (x,y)
+ * param[in] sizePub is the size of 'pub' in bytes.
+ * param[out] out output buffer to hold shared secret
+ * param[in] sizeOut size of out buffer
+ * param keyType type of ECC key i.e P256 / P384
+ * param enc option to use black key
+ * return Operation status.
+ */
+status_t CAAM_ECC_ECDH(CAAM_Type *base,
+ caam_handle_t *handle,
+ const uint8_t *k,
+ size_t sizeK,
+ const uint8_t *pub,
+ size_t sizePub,
+ uint8_t *out,
+ size_t sizeOut,
+ int keyType,
+ uint32_t enc)
+{
+ size_t keySz = 0;
+ caam_desc_pkha_ecc_t descriptor;
+ status_t status = kStatus_InvalidArgument;
+ uint32_t descriptorSize = ARRAY_SIZE(templateAgreeECC);
+ BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateAgreeECC), caam_desc_pkha_ecc_t_size_too_low);
+
+ /* check if known type of key encryption */
+ if (enc != 0 && enc != CAAM_PKHA_ENC_PRI_AESECB) {
+ return status;
+ }
+
+ /* check is supported key type */
+ keySz = CheckSupportedKeyType(keyType);
+ if (keySz == 0 || sizeK > keySz || sizeOut != keySz) {
+ return status;
+ }
+
+ /* initialize descriptor from template */
+ (void)caam_memcpy(descriptor, templateAgreeECC, sizeof(templateAgreeECC));
+
+ /* add descriptor length in bytes to HEADER descriptor command */
+ DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
+
+ DESC_SET_ADDR(descriptor[1], (CAAM_ECDSA_KEYGEN_PD | keyType));
+ DESC_SET_ADDR(descriptor[2], pub);
+ DESC_SET_ADDR(descriptor[3], k);
+ DESC_SET_ADDR(descriptor[4], out);
+
+ /* add in if is encrypted */
+ descriptor[5] |= enc;
+
+ /* schedule the job */
+ do {
+ status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
+ } while (status == kStatus_CAAM_Again);
+ if (status == kStatus_Success) {
+ status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
+ }
+
+#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
+ /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
+ /* Invalidate unaligned data can cause memory corruption in write-back mode */
+ DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
+#endif /* CAAM_OUT_INVALIDATE */
+ return status;
+}
+
+
+/* Handle BLOB create and open */
+static const uint32_t templateBlob[] = {
+ /* 00 */ 0xB0800000u, /* HEADER */
+ /* 01 */ 0x04000000u, /* class */
+ /* 02 */ 0x00000000u, /* key mod */
+ /* 03 */ 0xF0000000u, /* SEQ input size */
+ /* 04 */ 0x00000000u, /* input */
+ /* 05 */ 0xF8000000u, /* SEQ output size */
+ /* 06 */ 0x00000000u, /* output */
+ /* 07 */ 0x800D0000u, /* Operation */
+};
+
+
+/*!
+ * brief generate ECC Keypair.
+ *
+ * This function generates ECC private/public key pair.
+ *
+ * param base CAAM peripheral base address
+ * param[out] k private key
+ * param[in,out] sizeK pointer to size variable. On input it holds size of input k in bytes. On output it holds size of
+ * of generated private key k in bytes.
+ * param[out] p public key
+ * param[in,out] sizeP pointer to size variable. On input it holds size of input p in bytes. On output it holds size of
+ * of generated public key p in bytes.
+ * param keyType type of ECC key, i.e P256 / P384
+ * param enc option to create black key
+ * return Operation status.
+ */
+status_t CAAM_Blob(CAAM_Type *base,
+ caam_handle_t *handle,
+ uint8_t *in,
+ size_t sizeIn,
+ uint8_t *out,
+ size_t sizeOut,
+ uint8_t *keyMod,
+ size_t keyModSz,
+ uint32_t dir,
+ uint32_t color)
+{
+ caam_desc_pkha_ecc_t descriptor;
+ status_t status = kStatus_InvalidArgument;
+ uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
+ BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateBlob), caam_desc_pkha_ecc_t_size_too_low);
+
+ /* check if known type of key encryption */
+ if (color != CAAM_RED_BLOB && color != CAAM_BLACK_BLOB) {
+ return status;
+ }
+
+ if (dir != CAAM_ENCAP_BLOB && dir != CAAM_DECAP_BLOB) {
+ return status;
+ }
+
+ /* simple sanity check on output size to avoid invalidating more
+ * than wanted */
+ if (dir == CAAM_ENCAP_BLOB &&
+ (sizeOut > sizeIn + CAAM_PADDING_SIZE_BLOB)) {
+ return status;
+ }
+
+ if (keyModSz != CAAM_SM_KEYMODSZ && keyModSz != CAAM_KEYMODSZ) {
+ return status;
+ }
+
+ if (dir == CAAM_DECAP_BLOB &&
+ (sizeOut > sizeIn - CAAM_PADDING_SIZE_BLOB)) {
+ return status;
+ }
+
+ /* initialize descriptor from template */
+ (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
+
+ /* add descriptor length in bytes to HEADER descriptor command */
+ DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
+ descriptor[1] |= keyModSz;
+ DESC_SET_ADDR(descriptor[2], keyMod);
+ DESC_ADD_LEN(descriptor[3], sizeIn);
+ DESC_SET_ADDR(descriptor[4], in);
+ DESC_ADD_LEN(descriptor[5], sizeOut);
+ DESC_SET_ADDR(descriptor[6], out);
+ descriptor[7] |= dir; /* add in direction of blob (encap / decap) */
+
+ /* set black key flag */
+ if (color == CAAM_BLACK_BLOB) {
+ descriptor[7] |= 0x4; /* ECB black key */
+ /* additionally AES-CCM would have EXT (bit 8) hot */
+ }
+
+ /* schedule the job */
+ do {
+ status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
+ } while (status == kStatus_CAAM_Again);
+ if (status == kStatus_Success) {
+ status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
+ }
+
+#if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
+ /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
+ /* Invalidate unaligned data can cause memory corruption in write-back mode */
+ DCACHE_InvalidateByRange((uint32_t)out, sizeOut);
+#endif /* CAAM_OUT_INVALIDATE */
+ return status;
+}
+