123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- --- fsl_caam-orig.c 2022-10-21 15:50:35.709951000 -0700
- +++ fsl_caam.c 2022-12-28 06:30:34.788316189 -0800
- @@ -7872,3 +7872,462 @@
- }
- 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 lenght 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 */
- + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
- + 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 lenght 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 */
- + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
- + 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 lenght 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 */
- + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
- + 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 lenght 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 */
- + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
- + 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 */ 0x14400000u, /* 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 (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 lenght in bytes to HEADER descriptor command */
- + DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
- + descriptor[1] |= color; /* add color of blob */
- + 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 */
- + status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
- + 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;
- +}
- +
|