Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h 2 : #define HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h 3 : 4 : #include "../fd_quic_common.h" 5 : #include "../fd_quic_enum.h" 6 : #include "../fd_quic_conn_id.h" 7 : #include "../../../ballet/aes/fd_aes_gcm.h" 8 : 9 : /* Defines the crypto suites used by QUIC v1. 10 : 11 : QUIC v2 is defined here: 12 : https://www.rfc-editor.org/rfc/rfc9001.html#name-header-protection 13 : https://www.rfc-editor.org/rfc/rfc8446.html#page-133 14 : 15 : The suites are defined thusly: 16 : 17 : +------------------------------+-------------+ 18 : | Description | Value | 19 : +------------------------------+-------------+ 20 : | TLS_AES_128_GCM_SHA256 | {0x13,0x01} | 21 : | TLS_AES_256_GCM_SHA384 | {0x13,0x02} | 22 : | TLS_CHACHA20_POLY1305_SHA256 | {0x13,0x03} | 23 : | TLS_AES_128_CCM_SHA256 | {0x13,0x04} | 24 : | TLS_AES_128_CCM_8_SHA256 | {0x13,0x05} | 25 : +------------------------------+-------------+ 26 : 27 : Notes: 28 : TLS_AES_128_CCM_SHA256 does not seem to be mentioned in rfc9001, so is excluded 29 : TLS_AES_128_CCM_8_SHA256 has no packet-header encryption defined, and so must be excluded 30 : 31 : The remainder are defined below */ 32 : 33 : typedef struct fd_quic_crypto_keys fd_quic_crypto_keys_t; 34 : typedef struct fd_quic_crypto_secrets fd_quic_crypto_secrets_t; 35 : 36 215286716 : #define FD_QUIC_CRYPTO_TAG_SZ 16 37 39809492 : #define FD_QUIC_CRYPTO_SAMPLE_SZ 16 38 : 39 : struct fd_quic_crypto_keys { 40 : /* packet protection: */ 41 : uchar pkt_key[FD_AES_128_KEY_SZ]; 42 : uchar iv [FD_AES_GCM_IV_SZ ]; 43 : uchar hp_key [FD_AES_128_KEY_SZ]; 44 : }; 45 : 46 : /* define enums for encryption levels */ 47 63205959 : #define fd_quic_enc_level_initial_id 0 48 : #define fd_quic_enc_level_early_data_id 1 49 51971102 : #define fd_quic_enc_level_handshake_id 2 50 179218472 : #define fd_quic_enc_level_appdata_id 3 51 : #define FD_QUIC_NUM_ENC_LEVELS 4 52 : 53 : /* labels defined in rfc9001 */ 54 24792 : #define FD_QUIC_CRYPTO_LABEL_CLIENT_IN "client in" 55 24792 : #define FD_QUIC_CRYPTO_LABEL_SERVER_IN "server in" 56 : 57 145968 : #define FD_QUIC_CRYPTO_LABEL_QUIC_KEY "quic key" 58 145968 : #define FD_QUIC_CRYPTO_LABEL_QUIC_IV "quic iv" 59 145776 : #define FD_QUIC_CRYPTO_LABEL_QUIC_HP "quic hp" 60 : 61 192 : #define FD_QUIC_CRYPTO_LABEL_KEY_UPDATE "quic ku" 62 : 63 : /* each of these has "-1" to avoid counting the implied terminating NUL byte */ 64 12396 : #define FD_QUIC_CRYPTO_LABEL_CLIENT_IN_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_CLIENT_IN ) - 1 ) 65 12396 : #define FD_QUIC_CRYPTO_LABEL_SERVER_IN_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_SERVER_IN ) - 1 ) 66 : 67 72984 : #define FD_QUIC_CRYPTO_LABEL_QUIC_KEY_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_KEY ) - 1 ) 68 72984 : #define FD_QUIC_CRYPTO_LABEL_QUIC_IV_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_IV ) - 1 ) 69 72888 : #define FD_QUIC_CRYPTO_LABEL_QUIC_HP_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_HP ) - 1 ) 70 : 71 96 : #define FD_QUIC_CRYPTO_LABEL_KEY_UPDATE_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_KEY_UPDATE ) - 1 ) 72 : 73 : struct fd_quic_crypto_secrets { 74 : uchar initial_secret[FD_QUIC_INITIAL_SECRET_SZ]; 75 : 76 : /* a secret for each encryption level, and one for us (is_peer=0), and one for them */ 77 : /* secret[enc_level][is_peer][0..FD_QUIC_MAX_SECRET_SZ] */ 78 : uchar secret[FD_QUIC_NUM_ENC_LEVELS][2][FD_QUIC_SECRET_SZ]; 79 : 80 : /* new secret for switching keys during key update */ 81 : uchar new_secret [2][FD_QUIC_SECRET_SZ]; 82 : uchar new_secret_sz[2]; 83 : }; 84 : 85 : /* fd_quic_gen_initial_secret generates the initial secret according to spec 86 : 87 : args 88 : secrets a pointer to the structure to receive the secrets data 89 : conn_id the raw connection id required to generate the secrets 90 : conn_id_sz the size of the raw connection id */ 91 : void 92 : fd_quic_gen_initial_secret( 93 : fd_quic_crypto_secrets_t * secrets, 94 : uchar const * conn_id, 95 : ulong conn_id_sz ); 96 : 97 : /* fd_quic_gen_secrets generate secrets according to the aforementioned RFCs 98 : 99 : args 100 : secrets a pointer to the structure to receive the secrets data 101 : enc_level the encryption level to update */ 102 : void 103 : fd_quic_gen_secrets( 104 : fd_quic_crypto_secrets_t * secrets, 105 : uint enc_level ); 106 : 107 : 108 : /* generate new secrets 109 : 110 : Used during key update to generate new secrets from the 111 : existing secrets 112 : 113 : see rfc9001 section 6, rfc8446 section 7.2 */ 114 : void 115 : fd_quic_gen_new_secrets( fd_quic_crypto_secrets_t * secrets ); 116 : 117 : 118 : /* fd_quic_gen_keys 119 : 120 : generate the keys used for encrypting and decrypting from the given secrets 121 : and associated data 122 : 123 : args 124 : keys a pointer to the structure to receive the generated keys 125 : secret a pointer to the secret used for generating the keys */ 126 : void 127 : fd_quic_gen_keys( 128 : fd_quic_crypto_keys_t * keys, 129 : uchar const secret[ 32 ] ); 130 : 131 : 132 : /* generates packet key and iv key 133 : used by key update 134 : 135 : TODO this overlaps with fd_quic_gen_keys, split into gen_hp_keys and gen_pkt_keys */ 136 : void 137 : fd_quic_gen_new_keys( 138 : fd_quic_crypto_keys_t * keys, 139 : uchar const secret[ 32 ] ); 140 : 141 : /* encrypt a packet according to rfc9001 packet protection and header protection 142 : 143 : may fail in the following scenarios: 144 : the receiving buffer is too small 145 : the decryption functions report failure (fd_tls) 146 : 147 : returns 148 : FD_QUIC_SUCCESS if the operation succeeded 149 : FD_QUIC_FAILED otherwise 150 : 151 : args 152 : out destination for the full packet 153 : out_sz size of the output buffer, and also returned size of the written bytes 154 : hdr the input plain text header 155 : hdr_sz the size of the input header 156 : pkt the input plain text payload 157 : pkt_sz the size of the input payload 158 : keys the keys to use 159 : */ 160 : int 161 : fd_quic_crypto_encrypt( 162 : uchar * const out, 163 : ulong * const out_sz, 164 : uchar const * const hdr, 165 : ulong const hdr_sz, 166 : uchar const * const pkt, 167 : ulong const pkt_sz, 168 : fd_quic_crypto_keys_t const * const pkt_keys, 169 : fd_quic_crypto_keys_t const * const hp_keys, 170 : ulong const pkt_number ); 171 : 172 : 173 : /* decrypt a quic protected packet 174 : 175 : may fail in the following scenarios: 176 : the receiving buffer is too small 177 : the decryption functions report failure (fd_tls) 178 : the decrypted data is corrupt 179 : 180 : returns 181 : FD_QUIC_SUCCESS if the operation succeeded 182 : FD_QUIC_FAILED otherwise 183 : 184 : args 185 : buf buffer containing a QUIC packet with a decrypted 186 : header, and encrypted payload, and the auth tag 187 : of size FD_QUIC_CRYPTO_TAG_SZ. On return, the 188 : payload will be decrypted. 189 : buf_sz the size of the QUIC packet 190 : pkt_number_off the offset of the packet number within the cipher text 191 : this must be determined from unprotected header data 192 : keys the keys needed to decrypt */ 193 : 194 : int 195 : fd_quic_crypto_decrypt( 196 : uchar * buf, 197 : ulong buf_sz, 198 : ulong pkt_number_off, 199 : ulong pkt_number, 200 : fd_quic_crypto_keys_t const * keys ); 201 : 202 : 203 : /* decrypt a quic protected packet header 204 : 205 : this removes header protection (HP) 206 : 207 : may fail in the following scenarios: 208 : the receiving buffer is too small 209 : the decryption functions report failure (fd_tls) 210 : the decrypted data is corrupt 211 : 212 : returns 213 : FD_QUIC_SUCCESS if the operation succeeded 214 : FD_QUIC_FAILED otherwise 215 : 216 : args 217 : buf buffer containing an encrypted QUIC packet. 218 : On return, the header is decrypted, the rest 219 : still encrypted 220 : buf_sz size of the QUIC packet 221 : pkt_number_off the offset of the packet number within the cipher text 222 : this must be determined from unprotected header data 223 : keys the keys needed to decrypt */ 224 : 225 : int 226 : fd_quic_crypto_decrypt_hdr( 227 : uchar * buf, 228 : ulong buf_sz, 229 : ulong pkt_number_off, 230 : fd_quic_crypto_keys_t const * keys ); 231 : 232 : #endif /* HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h */