// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC #include #include #include #include #include "../fipsmodule/delocate.h" #include "../internal.h" #include "internal.h" // The KEM parameters listed below are taken from corresponding specifications. // // Kyber: - https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf // - Kyber is not standardized yet, so we use the latest specification // from Round 3 of NIST PQC project. #define AWSLC_NUM_BUILT_IN_KEMS 3 // TODO(awslc): placeholder OIDs, replace with the real ones when available. static const uint8_t kOIDKyber512r3[] = {0xff, 0xff, 0xff, 0xff}; static const uint8_t kOIDKyber768r3[] = {0xff, 0xff, 0xff, 0xff}; static const uint8_t kOIDKyber1024r3[] = {0xff, 0xff, 0xff, 0xff}; static const KEM built_in_kems[AWSLC_NUM_BUILT_IN_KEMS] = { { NID_KYBER512_R3, // kem.nid kOIDKyber512r3, // kem.oid sizeof(kOIDKyber512r3), // kem.oid_len "Kyber512 Round-3", // kem.comment 800, // kem.public_key_len 1632, // kem.secret_key_len 768, // kem.ciphertext_len 32, // kem.shared_secret_len &kem_kyber512r3_method, // kem.method }, { NID_KYBER768_R3, // kem.nid kOIDKyber768r3, // kem.oid sizeof(kOIDKyber768r3), // kem.oid_len "Kyber768 Round-3", // kem.comment 1184, // kem.public_key_len 2400, // kem.secret_key_len 1088, // kem.ciphertext_len 32, // kem.shared_secret_len &kem_kyber768r3_method, // kem.method }, { NID_KYBER1024_R3, // kem.nid kOIDKyber1024r3, // kem.oid sizeof(kOIDKyber1024r3), // kem.oid_len "Kyber1024 Round-3", // kem.comment 1568, // kem.public_key_len 3168, // kem.secret_key_len 1568, // kem.ciphertext_len 32, // kem.shared_secret_len &kem_kyber1024r3_method, // kem.method }, }; const KEM *KEM_find_kem_by_nid(int nid) { const KEM *ret = NULL; for (size_t i = 0; i < AWSLC_NUM_BUILT_IN_KEMS; i++) { if (built_in_kems[i].nid == nid) { ret = &built_in_kems[i]; break; } } return ret; } KEM_KEY *KEM_KEY_new(void) { KEM_KEY *ret = OPENSSL_malloc(sizeof(KEM_KEY)); if (ret == NULL) { return NULL; } OPENSSL_memset(ret, 0, sizeof(KEM_KEY)); return ret; } static void KEM_KEY_clear(KEM_KEY *key) { key->kem = NULL; OPENSSL_free(key->public_key); OPENSSL_free(key->secret_key); key->public_key = NULL; key->secret_key = NULL; } int KEM_KEY_init(KEM_KEY *key, const KEM *kem) { if (key == NULL || kem == NULL) { return 0; } // If the key is already initialized clear it. KEM_KEY_clear(key); key->kem = kem; key->public_key = OPENSSL_malloc(kem->public_key_len); key->secret_key = OPENSSL_malloc(kem->secret_key_len); if (key->public_key == NULL || key->secret_key == NULL) { KEM_KEY_clear(key); return 0; } return 1; } void KEM_KEY_free(KEM_KEY *key) { if (key == NULL) { return; } KEM_KEY_clear(key); OPENSSL_free(key); } const KEM *KEM_KEY_get0_kem(KEM_KEY* key) { return key->kem; } int KEM_KEY_set_raw_public_key(KEM_KEY *key, const uint8_t *in) { key->public_key = OPENSSL_memdup(in, key->kem->public_key_len); if (key->public_key == NULL) { return 0; } return 1; } int KEM_KEY_set_raw_secret_key(KEM_KEY *key, const uint8_t *in) { key->secret_key = OPENSSL_memdup(in, key->kem->secret_key_len); if (key->secret_key == NULL) { return 0; } return 1; } int KEM_KEY_set_raw_key(KEM_KEY *key, const uint8_t *in_public, const uint8_t *in_secret) { key->public_key = OPENSSL_memdup(in_public, key->kem->public_key_len); key->secret_key = OPENSSL_memdup(in_secret, key->kem->secret_key_len); if (key->public_key == NULL || key->secret_key == NULL) { KEM_KEY_clear(key); return 0; } return 1; }