1*e7be843bSPierre Pronchery /* 2*e7be843bSPierre Pronchery * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. 3*e7be843bSPierre Pronchery * 4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5*e7be843bSPierre Pronchery * this file except in compliance with the License. You can obtain a copy 6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at 7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html 8*e7be843bSPierre Pronchery */ 9*e7be843bSPierre Pronchery 10*e7be843bSPierre Pronchery /* APIs and data structures for HPKE (RFC9180) */ 11*e7be843bSPierre Pronchery #ifndef OSSL_HPKE_H 12*e7be843bSPierre Pronchery # define OSSL_HPKE_H 13*e7be843bSPierre Pronchery # pragma once 14*e7be843bSPierre Pronchery 15*e7be843bSPierre Pronchery # include <openssl/types.h> 16*e7be843bSPierre Pronchery 17*e7be843bSPierre Pronchery /* HPKE modes */ 18*e7be843bSPierre Pronchery # define OSSL_HPKE_MODE_BASE 0 /* Base mode */ 19*e7be843bSPierre Pronchery # define OSSL_HPKE_MODE_PSK 1 /* Pre-shared key mode */ 20*e7be843bSPierre Pronchery # define OSSL_HPKE_MODE_AUTH 2 /* Authenticated mode */ 21*e7be843bSPierre Pronchery # define OSSL_HPKE_MODE_PSKAUTH 3 /* PSK+authenticated mode */ 22*e7be843bSPierre Pronchery 23*e7be843bSPierre Pronchery /* 24*e7be843bSPierre Pronchery * Max for ikm, psk, pskid, info and exporter contexts. 25*e7be843bSPierre Pronchery * RFC9180, section 7.2.1 RECOMMENDS 64 octets but we have test vectors from 26*e7be843bSPierre Pronchery * Appendix A.6.1 with a 66 octet IKM so we'll allow that. 27*e7be843bSPierre Pronchery */ 28*e7be843bSPierre Pronchery # define OSSL_HPKE_MAX_PARMLEN 66 29*e7be843bSPierre Pronchery # define OSSL_HPKE_MIN_PSKLEN 32 30*e7be843bSPierre Pronchery # define OSSL_HPKE_MAX_INFOLEN 1024 31*e7be843bSPierre Pronchery 32*e7be843bSPierre Pronchery /* 33*e7be843bSPierre Pronchery * The (16bit) HPKE algorithm ID IANA codepoints 34*e7be843bSPierre Pronchery * If/when new IANA codepoints are added there are tables in 35*e7be843bSPierre Pronchery * crypto/hpke/hpke_util.c that must also be updated. 36*e7be843bSPierre Pronchery */ 37*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_RESERVED 0x0000 /* not used */ 38*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_P256 0x0010 /* NIST P-256 */ 39*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_P384 0x0011 /* NIST P-384 */ 40*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_P521 0x0012 /* NIST P-521 */ 41*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_X25519 0x0020 /* Curve25519 */ 42*e7be843bSPierre Pronchery # define OSSL_HPKE_KEM_ID_X448 0x0021 /* Curve448 */ 43*e7be843bSPierre Pronchery 44*e7be843bSPierre Pronchery # define OSSL_HPKE_KDF_ID_RESERVED 0x0000 /* not used */ 45*e7be843bSPierre Pronchery # define OSSL_HPKE_KDF_ID_HKDF_SHA256 0x0001 /* HKDF-SHA256 */ 46*e7be843bSPierre Pronchery # define OSSL_HPKE_KDF_ID_HKDF_SHA384 0x0002 /* HKDF-SHA384 */ 47*e7be843bSPierre Pronchery # define OSSL_HPKE_KDF_ID_HKDF_SHA512 0x0003 /* HKDF-SHA512 */ 48*e7be843bSPierre Pronchery 49*e7be843bSPierre Pronchery # define OSSL_HPKE_AEAD_ID_RESERVED 0x0000 /* not used */ 50*e7be843bSPierre Pronchery # define OSSL_HPKE_AEAD_ID_AES_GCM_128 0x0001 /* AES-GCM-128 */ 51*e7be843bSPierre Pronchery # define OSSL_HPKE_AEAD_ID_AES_GCM_256 0x0002 /* AES-GCM-256 */ 52*e7be843bSPierre Pronchery # define OSSL_HPKE_AEAD_ID_CHACHA_POLY1305 0x0003 /* Chacha20-Poly1305 */ 53*e7be843bSPierre Pronchery # define OSSL_HPKE_AEAD_ID_EXPORTONLY 0xFFFF /* export-only fake ID */ 54*e7be843bSPierre Pronchery 55*e7be843bSPierre Pronchery /* strings for suite components */ 56*e7be843bSPierre Pronchery # define OSSL_HPKE_KEMSTR_P256 "P-256" /* KEM id 0x10 */ 57*e7be843bSPierre Pronchery # define OSSL_HPKE_KEMSTR_P384 "P-384" /* KEM id 0x11 */ 58*e7be843bSPierre Pronchery # define OSSL_HPKE_KEMSTR_P521 "P-521" /* KEM id 0x12 */ 59*e7be843bSPierre Pronchery # define OSSL_HPKE_KEMSTR_X25519 "X25519" /* KEM id 0x20 */ 60*e7be843bSPierre Pronchery # define OSSL_HPKE_KEMSTR_X448 "X448" /* KEM id 0x21 */ 61*e7be843bSPierre Pronchery # define OSSL_HPKE_KDFSTR_256 "hkdf-sha256" /* KDF id 1 */ 62*e7be843bSPierre Pronchery # define OSSL_HPKE_KDFSTR_384 "hkdf-sha384" /* KDF id 2 */ 63*e7be843bSPierre Pronchery # define OSSL_HPKE_KDFSTR_512 "hkdf-sha512" /* KDF id 3 */ 64*e7be843bSPierre Pronchery # define OSSL_HPKE_AEADSTR_AES128GCM "aes-128-gcm" /* AEAD id 1 */ 65*e7be843bSPierre Pronchery # define OSSL_HPKE_AEADSTR_AES256GCM "aes-256-gcm" /* AEAD id 2 */ 66*e7be843bSPierre Pronchery # define OSSL_HPKE_AEADSTR_CP "chacha20-poly1305" /* AEAD id 3 */ 67*e7be843bSPierre Pronchery # define OSSL_HPKE_AEADSTR_EXP "exporter" /* AEAD id 0xff */ 68*e7be843bSPierre Pronchery 69*e7be843bSPierre Pronchery /* 70*e7be843bSPierre Pronchery * Roles for use in creating an OSSL_HPKE_CTX, most 71*e7be843bSPierre Pronchery * important use of this is to control nonce reuse. 72*e7be843bSPierre Pronchery */ 73*e7be843bSPierre Pronchery # define OSSL_HPKE_ROLE_SENDER 0 74*e7be843bSPierre Pronchery # define OSSL_HPKE_ROLE_RECEIVER 1 75*e7be843bSPierre Pronchery 76*e7be843bSPierre Pronchery # ifdef __cplusplus 77*e7be843bSPierre Pronchery extern "C" { 78*e7be843bSPierre Pronchery # endif 79*e7be843bSPierre Pronchery 80*e7be843bSPierre Pronchery typedef struct { 81*e7be843bSPierre Pronchery uint16_t kem_id; /* Key Encapsulation Method id */ 82*e7be843bSPierre Pronchery uint16_t kdf_id; /* Key Derivation Function id */ 83*e7be843bSPierre Pronchery uint16_t aead_id; /* AEAD alg id */ 84*e7be843bSPierre Pronchery } OSSL_HPKE_SUITE; 85*e7be843bSPierre Pronchery 86*e7be843bSPierre Pronchery /** 87*e7be843bSPierre Pronchery * Suite constants, use this like: 88*e7be843bSPierre Pronchery * OSSL_HPKE_SUITE myvar = OSSL_HPKE_SUITE_DEFAULT; 89*e7be843bSPierre Pronchery */ 90*e7be843bSPierre Pronchery # ifndef OPENSSL_NO_ECX 91*e7be843bSPierre Pronchery # define OSSL_HPKE_SUITE_DEFAULT \ 92*e7be843bSPierre Pronchery {\ 93*e7be843bSPierre Pronchery OSSL_HPKE_KEM_ID_X25519, \ 94*e7be843bSPierre Pronchery OSSL_HPKE_KDF_ID_HKDF_SHA256, \ 95*e7be843bSPierre Pronchery OSSL_HPKE_AEAD_ID_AES_GCM_128 \ 96*e7be843bSPierre Pronchery } 97*e7be843bSPierre Pronchery # else 98*e7be843bSPierre Pronchery # define OSSL_HPKE_SUITE_DEFAULT \ 99*e7be843bSPierre Pronchery {\ 100*e7be843bSPierre Pronchery OSSL_HPKE_KEM_ID_P256, \ 101*e7be843bSPierre Pronchery OSSL_HPKE_KDF_ID_HKDF_SHA256, \ 102*e7be843bSPierre Pronchery OSSL_HPKE_AEAD_ID_AES_GCM_128 \ 103*e7be843bSPierre Pronchery } 104*e7be843bSPierre Pronchery #endif 105*e7be843bSPierre Pronchery 106*e7be843bSPierre Pronchery typedef struct ossl_hpke_ctx_st OSSL_HPKE_CTX; 107*e7be843bSPierre Pronchery 108*e7be843bSPierre Pronchery OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role, 109*e7be843bSPierre Pronchery OSSL_LIB_CTX *libctx, const char *propq); 110*e7be843bSPierre Pronchery void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx); 111*e7be843bSPierre Pronchery 112*e7be843bSPierre Pronchery int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx, 113*e7be843bSPierre Pronchery unsigned char *enc, size_t *enclen, 114*e7be843bSPierre Pronchery const unsigned char *pub, size_t publen, 115*e7be843bSPierre Pronchery const unsigned char *info, size_t infolen); 116*e7be843bSPierre Pronchery int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx, 117*e7be843bSPierre Pronchery unsigned char *ct, size_t *ctlen, 118*e7be843bSPierre Pronchery const unsigned char *aad, size_t aadlen, 119*e7be843bSPierre Pronchery const unsigned char *pt, size_t ptlen); 120*e7be843bSPierre Pronchery 121*e7be843bSPierre Pronchery int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite, 122*e7be843bSPierre Pronchery unsigned char *pub, size_t *publen, EVP_PKEY **priv, 123*e7be843bSPierre Pronchery const unsigned char *ikm, size_t ikmlen, 124*e7be843bSPierre Pronchery OSSL_LIB_CTX *libctx, const char *propq); 125*e7be843bSPierre Pronchery int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx, 126*e7be843bSPierre Pronchery const unsigned char *enc, size_t enclen, 127*e7be843bSPierre Pronchery EVP_PKEY *recippriv, 128*e7be843bSPierre Pronchery const unsigned char *info, size_t infolen); 129*e7be843bSPierre Pronchery int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx, 130*e7be843bSPierre Pronchery unsigned char *pt, size_t *ptlen, 131*e7be843bSPierre Pronchery const unsigned char *aad, size_t aadlen, 132*e7be843bSPierre Pronchery const unsigned char *ct, size_t ctlen); 133*e7be843bSPierre Pronchery 134*e7be843bSPierre Pronchery int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx, 135*e7be843bSPierre Pronchery unsigned char *secret, 136*e7be843bSPierre Pronchery size_t secretlen, 137*e7be843bSPierre Pronchery const unsigned char *label, 138*e7be843bSPierre Pronchery size_t labellen); 139*e7be843bSPierre Pronchery 140*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv); 141*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx, 142*e7be843bSPierre Pronchery const unsigned char *pub, 143*e7be843bSPierre Pronchery size_t publen); 144*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx, 145*e7be843bSPierre Pronchery const char *pskid, 146*e7be843bSPierre Pronchery const unsigned char *psk, size_t psklen); 147*e7be843bSPierre Pronchery 148*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx, 149*e7be843bSPierre Pronchery const unsigned char *ikme, size_t ikmelen); 150*e7be843bSPierre Pronchery 151*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq); 152*e7be843bSPierre Pronchery int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq); 153*e7be843bSPierre Pronchery 154*e7be843bSPierre Pronchery int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite); 155*e7be843bSPierre Pronchery int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in, 156*e7be843bSPierre Pronchery OSSL_HPKE_SUITE *suite, 157*e7be843bSPierre Pronchery unsigned char *enc, size_t *enclen, 158*e7be843bSPierre Pronchery unsigned char *ct, size_t ctlen, 159*e7be843bSPierre Pronchery OSSL_LIB_CTX *libctx, const char *propq); 160*e7be843bSPierre Pronchery int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite); 161*e7be843bSPierre Pronchery size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen); 162*e7be843bSPierre Pronchery size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite); 163*e7be843bSPierre Pronchery size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite); 164*e7be843bSPierre Pronchery 165*e7be843bSPierre Pronchery # ifdef __cplusplus 166*e7be843bSPierre Pronchery } 167*e7be843bSPierre Pronchery # endif 168*e7be843bSPierre Pronchery 169*e7be843bSPierre Pronchery #endif 170