summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJorge Ramirez-Ortiz <jorge@foundries.io>2020-12-15 18:58:53 +0100
committerJérôme Forissier <jerome@forissier.org>2021-01-05 12:31:29 +0100
commitd419b2b23d8e3ff143693519429fb528d951b276 (patch)
tree43218ba392fd6333aec0ecbe7dd935e0ff1327a2 /core
parentfab914923b94fccbb1e77538a355a8cdcad6b9a4 (diff)
crypto: se050: adaptors: elliptic curve
APDU and utility functions required to support elliptic curve cryptography. Signed-off-by: Jorge Ramirez-Ortiz <jorge@foundries.io> Acked-by: Jens Wiklander <jens.wiklander@linaro.org> Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Diffstat (limited to 'core')
-rw-r--r--core/drivers/crypto/se050/adaptors/apis/apdu.c206
-rw-r--r--core/drivers/crypto/se050/adaptors/include/se050_apdu_apis.h27
-rw-r--r--core/drivers/crypto/se050/adaptors/include/se050_utils.h2
-rw-r--r--core/drivers/crypto/se050/adaptors/utils/utils.c15
4 files changed, 250 insertions, 0 deletions
diff --git a/core/drivers/crypto/se050/adaptors/apis/apdu.c b/core/drivers/crypto/se050/adaptors/apis/apdu.c
index 21ac2859..d00559f2 100644
--- a/core/drivers/crypto/se050/adaptors/apis/apdu.c
+++ b/core/drivers/crypto/se050/adaptors/apis/apdu.c
@@ -524,3 +524,209 @@ sss_status_t se050_scp03_send_rotate_cmd(pSe05xSession_t ctx,
return kStatus_SSS_Fail;
}
+
+static uint8_t *alloc_pubkey_buf(struct se050_ecc_keypub *keypub, size_t *len)
+{
+ size_t pubkey_len = 0;
+ uint8_t *pubkey = NULL;
+ uint8_t *buf = NULL;
+
+ pubkey_len = keypub->x_len + keypub->y_len + 1;
+ buf = malloc(pubkey_len);
+ if (!buf)
+ return NULL;
+
+ *buf = 0x04;
+ pubkey = buf + 1;
+ memcpy(pubkey, keypub->x, keypub->x_len);
+ memcpy(pubkey + keypub->x_len, keypub->y, keypub->y_len);
+ *len = pubkey_len;
+
+ return buf;
+}
+
+sss_status_t se050_ecc_gen_shared_secret(pSe05xSession_t ctx, uint32_t kid,
+ struct se050_ecc_keypub *keypub,
+ uint8_t *secret, size_t *len)
+{
+ smStatus_t status = SM_OK;
+ uint8_t *buf = NULL;
+ size_t pubkey_len = 0;
+
+ if (!keypub || !secret || !len)
+ return kStatus_SSS_Fail;
+
+ buf = alloc_pubkey_buf(keypub, &pubkey_len);
+ if (!buf)
+ return kStatus_SSS_Fail;
+
+ status = Se05x_API_ECGenSharedSecret(ctx, kid,
+ buf, pubkey_len, secret, len);
+ free(buf);
+ if (status != SM_OK)
+ return kStatus_SSS_Fail;
+
+ return kStatus_SSS_Success;
+}
+
+static sss_status_t set_ecc_public(Se05xSession_t *s_ctx,
+ Se05xPolicy_t *policy,
+ sss_se05x_object_t *k_object,
+ SE05x_TransientType_t type,
+ struct se050_ecc_keypub *keypub)
+{
+ size_t pubkey_len = 0;
+ smStatus_t status = SM_NOT_OK;
+ uint8_t *buf = NULL;
+
+ buf = alloc_pubkey_buf(keypub, &pubkey_len);
+ if (!buf)
+ return kStatus_SSS_Fail;
+
+ k_object->curve_id = keypub->curve;
+ status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
+ k_object->keyId,
+ keypub->curve,
+ NULL,
+ 0,
+ buf,
+ pubkey_len,
+ (SE05x_INS_t)type,
+ kSE05x_KeyPart_Public);
+ free(buf);
+ if (status != SM_OK)
+ return kStatus_SSS_Fail;
+
+ return kStatus_SSS_Success;
+}
+
+static sss_status_t set_ecc_private(Se05xSession_t *s_ctx,
+ Se05xPolicy_t *policy,
+ sss_se05x_object_t *k_object,
+ SE05x_TransientType_t type,
+ struct se050_ecc_keypair *keypair)
+{
+ smStatus_t status = SM_NOT_OK;
+
+ k_object->curve_id = keypair->pub.curve;
+ status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
+ k_object->keyId,
+ keypair->pub.curve,
+ keypair->d,
+ keypair->d_len,
+ NULL,
+ 0,
+ (SE05x_INS_t)type,
+ kSE05x_KeyPart_Private);
+ if (status != SM_OK)
+ return kStatus_SSS_Fail;
+
+ return kStatus_SSS_Success;
+}
+
+static sss_status_t set_ecc_pair(Se05xSession_t *s_ctx,
+ Se05xPolicy_t *policy,
+ sss_se05x_object_t *k_object,
+ SE05x_TransientType_t type,
+ struct se050_ecc_keypair *keypair)
+{
+ size_t pubkey_len = 0;
+ smStatus_t status = SM_NOT_OK;
+ uint8_t *buf = NULL;
+
+ buf = alloc_pubkey_buf(&keypair->pub, &pubkey_len);
+ if (!buf)
+ return kStatus_SSS_Fail;
+
+ k_object->curve_id = keypair->pub.curve;
+ status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
+ k_object->keyId,
+ keypair->pub.curve,
+ keypair->d,
+ keypair->d_len,
+ buf,
+ pubkey_len,
+ (SE05x_INS_t)type,
+ kSE05x_KeyPart_Pair);
+ free(buf);
+ if (status != SM_OK)
+ return kStatus_SSS_Fail;
+
+ return kStatus_SSS_Success;
+}
+
+sss_status_t se050_key_store_set_ecc_key_bin(sss_se05x_key_store_t *store,
+ sss_se05x_object_t *k_object,
+ struct se050_ecc_keypair *keypair,
+ struct se050_ecc_keypub *keypub)
+{
+ SE05x_TransientType_t type = kSE05x_TransientType_Transient;
+ Se05xPolicy_t policy = { };
+
+ if (!store || !store->session || !k_object)
+ return kStatus_SSS_Fail;
+
+ if (k_object->isPersistant)
+ type = kSE05x_TransientType_Persistent;
+
+ switch (k_object->objectType) {
+ case kSSS_KeyPart_Public:
+ if (!keypub)
+ return kStatus_SSS_Fail;
+
+ return set_ecc_public(&store->session->s_ctx,
+ &policy, k_object, type, keypub);
+ case kSSS_KeyPart_Private:
+ if (!keypair)
+ return kStatus_SSS_Fail;
+
+ return set_ecc_private(&store->session->s_ctx,
+ &policy, k_object, type, keypair);
+ case kSSS_KeyPart_Pair:
+ if (!keypair)
+ return kStatus_SSS_Fail;
+
+ return set_ecc_pair(&store->session->s_ctx,
+ &policy, k_object, type, keypair);
+ default:
+ return kStatus_SSS_Fail;
+ }
+}
+
+sss_status_t se050_key_store_get_ecc_key_bin(sss_se05x_key_store_t *store,
+ sss_se05x_object_t *k_object,
+ uint8_t *key, size_t *key_len)
+{
+ smStatus_t status = SM_NOT_OK;
+ uint8_t *buf = NULL;
+ size_t buflen = 0;
+
+ if (!store || !store->session || !k_object || !key || !key_len)
+ return kStatus_SSS_Fail;
+
+ switch (k_object->cipherType) {
+ case kSSS_CipherType_EC_NIST_P:
+ case kSSS_CipherType_EC_NIST_K:
+ case kSSS_CipherType_EC_BRAINPOOL:
+ case kSSS_CipherType_EC_BARRETO_NAEHRIG:
+ case kSSS_CipherType_EC_MONTGOMERY:
+ case kSSS_CipherType_EC_TWISTED_ED:
+ add_ecc_header(key, &buf, &buflen, k_object->curve_id);
+ status = Se05x_API_ReadObject(&store->session->s_ctx,
+ k_object->keyId, 0, 0,
+ buf, key_len);
+ if (status != SM_OK)
+ return kStatus_SSS_Fail;
+
+ *key_len += buflen;
+ buflen = *key_len;
+ get_ecc_raw_data(key, &buf, &buflen, k_object->curve_id);
+
+ /* return only the binary data */
+ *key_len = buflen;
+ memcpy(key, buf, buflen);
+ return kStatus_SSS_Success;
+ default:
+ return kStatus_SSS_Fail;
+ }
+}
diff --git a/core/drivers/crypto/se050/adaptors/include/se050_apdu_apis.h b/core/drivers/crypto/se050/adaptors/include/se050_apdu_apis.h
index b6247561..766d12e3 100644
--- a/core/drivers/crypto/se050/adaptors/include/se050_apdu_apis.h
+++ b/core/drivers/crypto/se050/adaptors/include/se050_apdu_apis.h
@@ -54,4 +54,31 @@ sss_status_t se050_get_free_memory(pSe05xSession_t ctx, uint16_t *t,
sss_status_t se050_scp03_send_rotate_cmd(pSe05xSession_t ctx,
struct s050_scp_rotate_cmd *cmd);
+struct se050_ecc_keypub {
+ uint8_t *x;
+ size_t x_len;
+ uint8_t *y;
+ size_t y_len;
+ uint32_t curve;
+};
+
+struct se050_ecc_keypair {
+ struct se050_ecc_keypub pub;
+ uint8_t *d;
+ size_t d_len;
+};
+
+sss_status_t se050_key_store_set_ecc_key_bin(sss_se05x_key_store_t *store,
+ sss_se05x_object_t *object,
+ struct se050_ecc_keypair *pair,
+ struct se050_ecc_keypub *pub);
+
+sss_status_t se050_key_store_get_ecc_key_bin(sss_se05x_key_store_t *store,
+ sss_se05x_object_t *object,
+ uint8_t *key, size_t *len);
+
+sss_status_t se050_ecc_gen_shared_secret(pSe05xSession_t ctx, uint32_t id,
+ struct se050_ecc_keypub *pub,
+ uint8_t *secret, size_t *len);
+
#endif /* SE050_APDU_APIS_H_ */
diff --git a/core/drivers/crypto/se050/adaptors/include/se050_utils.h b/core/drivers/crypto/se050/adaptors/include/se050_utils.h
index 95ecad61..e25067c1 100644
--- a/core/drivers/crypto/se050/adaptors/include/se050_utils.h
+++ b/core/drivers/crypto/se050/adaptors/include/se050_utils.h
@@ -33,8 +33,10 @@ struct s050_scp_rotate_cmd {
sss_status_t se050_get_oid(sss_key_object_mode_t type, uint32_t *val);
struct rsa_keypair;
+struct ecc_keypair;
uint32_t se050_rsa_keypair_from_nvm(struct rsa_keypair *key);
+uint32_t se050_ecc_keypair_from_nvm(struct ecc_keypair *key);
uint64_t se050_generate_private_key(uint32_t oid);
void se050_refcount_init_ctx(uint8_t **cnt);
diff --git a/core/drivers/crypto/se050/adaptors/utils/utils.c b/core/drivers/crypto/se050/adaptors/utils/utils.c
index 34dbdd05..83edf944 100644
--- a/core/drivers/crypto/se050/adaptors/utils/utils.c
+++ b/core/drivers/crypto/se050/adaptors/utils/utils.c
@@ -134,6 +134,21 @@ uint32_t se050_rsa_keypair_from_nvm(struct rsa_keypair *key)
return se050_key(key_id);
}
+uint32_t se050_ecc_keypair_from_nvm(struct ecc_keypair *key)
+{
+ uint64_t key_id = 0;
+
+ if (!key)
+ return 0;
+
+ if (crypto_bignum_num_bytes(key->d) != sizeof(uint64_t))
+ return 0;
+
+ crypto_bignum_bn2bin(key->d, (uint8_t *)&key_id);
+
+ return se050_key(key_id);
+}
+
uint64_t se050_generate_private_key(uint32_t oid)
{
return WATERMARKED(oid);