Branch data Line data Source code
1 : : /* 2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 : : * 4 : : * Licensed under the Apache License, Version 2.0 (the "License"). 5 : : * You may not use this file except in compliance with the License. 6 : : * A copy of the License is located at 7 : : * 8 : : * http://aws.amazon.com/apache2.0 9 : : * 10 : : * or in the "license" file accompanying this file. This file is distributed 11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 : : * express or implied. See the License for the specific language governing 13 : : * permissions and limitations under the License. 14 : : */ 15 : : 16 : : #pragma once 17 : : 18 : : #include <stdint.h> 19 : : 20 : : #include "crypto/s2n_ecc_evp.h" 21 : : #include "stuffer/s2n_stuffer.h" 22 : : #include "tls/s2n_crypto_constants.h" 23 : : #include "utils/s2n_blob.h" 24 : : 25 : : typedef uint16_t kem_extension_size; 26 : : typedef uint16_t kem_public_key_size; 27 : : typedef uint16_t kem_private_key_size; 28 : : typedef uint16_t kem_shared_secret_size; 29 : : typedef uint16_t kem_ciphertext_key_size; 30 : : 31 : : #define IN /* Indicates a necessary function input */ 32 : : #define OUT /* Indicates a function output */ 33 : : 34 : : #define S2N_NID_KYBER512 NID_undef 35 : : #define S2N_NID_KYBER768 NID_undef 36 : : #define S2N_NID_KYBER1024 NID_undef 37 : : 38 : : #if defined(S2N_LIBCRYPTO_SUPPORTS_MLKEM) 39 : : #define S2N_NID_MLKEM768 NID_MLKEM768 40 : : #define S2N_NID_MLKEM1024 NID_MLKEM1024 41 : : #else 42 : : #define S2N_NID_MLKEM768 NID_undef 43 : : #define S2N_NID_MLKEM1024 NID_undef 44 : : #endif 45 : : 46 : : struct s2n_kem { 47 : : const char *name; 48 : : int kem_nid; 49 : : const kem_extension_size kem_extension_id; 50 : : const kem_public_key_size public_key_length; 51 : : const kem_private_key_size private_key_length; 52 : : const kem_shared_secret_size shared_secret_key_length; 53 : : const kem_ciphertext_key_size ciphertext_length; 54 : : /* NIST Post Quantum KEM submissions require the following API for compatibility */ 55 : : int (*generate_keypair)(IN const struct s2n_kem *kem, OUT uint8_t *public_key, OUT uint8_t *private_key); 56 : : int (*encapsulate)(IN const struct s2n_kem *kem, OUT uint8_t *ciphertext, OUT uint8_t *shared_secret, IN const uint8_t *public_key); 57 : : int (*decapsulate)(IN const struct s2n_kem *kem, OUT uint8_t *shared_secret, IN const uint8_t *ciphertext, IN const uint8_t *private_key); 58 : : }; 59 : : 60 : : struct s2n_kem_params { 61 : : const struct s2n_kem *kem; 62 : : struct s2n_blob public_key; 63 : : struct s2n_blob private_key; 64 : : struct s2n_blob shared_secret; 65 : : /* Store whether the client included the length prefix of the PQ and ECC Shares in their ClientHello, so that the 66 : : * server can match the client's behavior. For the client side, store whether it should send the length prefix. */ 67 : : bool len_prefixed; 68 : : }; 69 : : 70 : : struct s2n_iana_to_kem { 71 : : const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN]; 72 : : const struct s2n_kem **kems; 73 : : uint8_t kem_count; 74 : : }; 75 : : 76 : : struct s2n_kem_group { 77 : : const char *name; 78 : : uint16_t iana_id; 79 : : const struct s2n_ecc_named_curve *curve; 80 : : const struct s2n_kem *kem; 81 : : 82 : : /* Whether the PQ KeyShare should be sent before the ECC KeyShare. Only enabled for X25519MLKEM768. 83 : : * See: https://datatracker.ietf.org/doc/html/draft-kwiatkowski-tls-ecdhe-mlkem-02#name-negotiated-groups */ 84 : : bool send_kem_first; 85 : : }; 86 : : 87 : : struct s2n_kem_group_params { 88 : : const struct s2n_kem_group *kem_group; 89 : : struct s2n_kem_params kem_params; 90 : : struct s2n_ecc_evp_params ecc_params; 91 : : }; 92 : : 93 : : extern const struct s2n_kem s2n_mlkem_768; 94 : : extern const struct s2n_kem s2n_mlkem_1024; 95 : : extern const struct s2n_kem s2n_kyber_512_r3; 96 : : extern const struct s2n_kem s2n_kyber_768_r3; 97 : : extern const struct s2n_kem s2n_kyber_1024_r3; 98 : : 99 : 44 : #define S2N_KEM_GROUPS_COUNT 10 100 : : extern const struct s2n_kem_group *ALL_SUPPORTED_KEM_GROUPS[S2N_KEM_GROUPS_COUNT]; 101 : : 102 : : /* NIST curve KEM Groups */ 103 : : extern const struct s2n_kem_group s2n_secp256r1_mlkem_768; 104 : : extern const struct s2n_kem_group s2n_secp384r1_mlkem_1024; 105 : : extern const struct s2n_kem_group s2n_secp256r1_kyber_512_r3; 106 : : extern const struct s2n_kem_group s2n_secp256r1_kyber_768_r3; 107 : : extern const struct s2n_kem_group s2n_secp384r1_kyber_768_r3; 108 : : extern const struct s2n_kem_group s2n_secp521r1_kyber_1024_r3; 109 : : 110 : : /* x25519 KEM Groups */ 111 : : extern const struct s2n_kem_group s2n_x25519_mlkem_768; 112 : : extern const struct s2n_kem_group s2n_x25519_kyber_512_r3; 113 : : extern const struct s2n_kem_group s2n_x25519_kyber_768_r3; 114 : : 115 : : /* Pure ML-KEM Groups */ 116 : : extern const struct s2n_kem_group s2n_pure_mlkem_1024; 117 : : 118 : : S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params); 119 : : S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext); 120 : : S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext); 121 : : int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], 122 : : struct s2n_blob *client_kem_ids, const struct s2n_kem *server_kem_pref_list[], 123 : : const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem); 124 : : int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], 125 : : const struct s2n_kem *server_kem_pref_list[], const uint8_t num_server_supported_kems, 126 : : const struct s2n_kem **chosen_kem); 127 : : int s2n_kem_free(struct s2n_kem_params *kem_params); 128 : : int s2n_kem_group_free(struct s2n_kem_group_params *kem_group_params); 129 : : int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], 130 : : const struct s2n_iana_to_kem **supported_params); 131 : : int s2n_get_kem_from_extension_id(kem_extension_size kem_id, const struct s2n_kem **kem); 132 : : int s2n_kem_send_public_key(struct s2n_stuffer *out, struct s2n_kem_params *kem_params); 133 : : int s2n_kem_recv_public_key(struct s2n_stuffer *in, struct s2n_kem_params *kem_params); 134 : : int s2n_kem_send_ciphertext(struct s2n_stuffer *out, struct s2n_kem_params *kem_params); 135 : : int s2n_kem_recv_ciphertext(struct s2n_stuffer *in, struct s2n_kem_params *kem_params); 136 : : bool s2n_kem_is_available(const struct s2n_kem *kem); 137 : : bool s2n_kem_group_is_available(const struct s2n_kem_group *kem_group); 138 : : int s2n_find_kem_group_from_iana_id(uint16_t iana_id, const struct s2n_kem_group **out, bool *found); 139 : : 140 : : /* mlkem768 */ 141 : : #define S2N_MLKEM_768_PUBLIC_KEY_BYTES 1184 142 : : #define S2N_MLKEM_768_SECRET_KEY_BYTES 2400 143 : : #define S2N_MLKEM_768_CIPHERTEXT_BYTES 1088 144 : : #define S2N_MLKEM_768_SHARED_SECRET_BYTES 32 145 : : 146 : : /* mlkem1024 */ 147 : : #define S2N_MLKEM_1024_PUBLIC_KEY_BYTES 1568 148 : : #define S2N_MLKEM_1024_SECRET_KEY_BYTES 3168 149 : : #define S2N_MLKEM_1024_CIPHERTEXT_BYTES 1568 150 : : #define S2N_MLKEM_1024_SHARED_SECRET_BYTES 32 151 : : 152 : : /* kyber512r3 */ 153 : : #define S2N_KYBER_512_R3_PUBLIC_KEY_BYTES 800 154 : : #define S2N_KYBER_512_R3_SECRET_KEY_BYTES 1632 155 : : #define S2N_KYBER_512_R3_CIPHERTEXT_BYTES 768 156 : : #define S2N_KYBER_512_R3_SHARED_SECRET_BYTES 32 157 : : 158 : : /* kyber768r3 */ 159 : : #define S2N_KYBER_768_R3_PUBLIC_KEY_BYTES 1184 160 : : #define S2N_KYBER_768_R3_SECRET_KEY_BYTES 2400 161 : : #define S2N_KYBER_768_R3_CIPHERTEXT_BYTES 1088 162 : : #define S2N_KYBER_768_R3_SHARED_SECRET_BYTES 32 163 : : 164 : : /* kyber1024r3 */ 165 : : #define S2N_KYBER_1024_R3_PUBLIC_KEY_BYTES 1568 166 : : #define S2N_KYBER_1024_R3_SECRET_KEY_BYTES 3168 167 : : #define S2N_KYBER_1024_R3_CIPHERTEXT_BYTES 1568 168 : : #define S2N_KYBER_1024_R3_SHARED_SECRET_BYTES 32