diff options
Diffstat (limited to 'crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h')
-rw-r--r-- | crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h b/crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h new file mode 100644 index 000000000000..4bf618ea0b79 --- /dev/null +++ b/crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h @@ -0,0 +1,98 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef PROV_ML_COMMON_CODECS_H +# define PROV_ML_COMMON_CODECS_H +# pragma once + +# include <openssl/e_os2.h> +# include "crypto/ml_dsa.h" +# include "prov/provider_ctx.h" + + /*- + * The DER ASN.1 encoding of ML-DSA and ML-KEM public keys prepends 22 bytes + * to the encoded public key: + * + * - 4 byte outer sequence tag and length + * - 2 byte algorithm sequence tag and length + * - 2 byte algorithm OID tag and length + * - 9 byte algorithm OID (from NIST CSOR OID arc) + * - 4 byte bit string tag and length + * - 1 bitstring lead byte + */ +# define ML_COMMON_SPKI_OVERHEAD 22 +typedef struct { + const uint8_t asn1_prefix[ML_COMMON_SPKI_OVERHEAD]; +} ML_COMMON_SPKI_FMT; + +/*- +* For each parameter set we support a few PKCS#8 input formats, three + * corresponding to the "either or both" variants of: + * + * ML-DSA-PrivateKey ::= CHOICE { + * seed [0] IMPLICIT OCTET STRING (SIZE (32)), + * expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)), + * both SEQUENCE { + * seed OCTET STRING (SIZE (32)), + * expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)) } } + * + * ML-KEM-PrivateKey ::= CHOICE { + * seed [0] IMPLICIT OCTET STRING (SIZE (64)), + * expandedKey OCTET STRING (SIZE (1632 | 2400 | 3168)), + * both SEQUENCE { + * seed OCTET STRING (SIZE (64)), + * expandedKey OCTET STRING SIZE ((1632 | 2400 | 3168)) } } + * + * one more for a historical OQS encoding: + * + * - OQS private + public key: OCTET STRING + * (The public key is ignored, just as with PKCS#8 v2.) + * + * and two more that are the minimal IETF non-ASN.1 seed encoding: + * + * - Bare seed (just the 32 or 64 bytes) + * - Bare priv (just the key bytes) + * + * A length of zero means that particular field is absent. + * + * The p8_shift is 0 when the top-level tag+length occupy four bytes, 2 when + * they occupy two by†es, and 4 when no tag is used at all. + */ +#define NUM_PKCS8_FORMATS 6 + +typedef struct { + const char *p8_name; /* Format name */ + size_t p8_bytes; /* Total P8 encoding length */ + int p8_shift; /* 4 - (top-level tag + len) */ + uint32_t p8_magic; /* The tag + len value */ + uint16_t seed_magic; /* Interior tag + len for the seed */ + size_t seed_offset; /* Seed offset from start */ + size_t seed_length; /* Seed bytes */ + uint32_t priv_magic; /* Interior tag + len for the key */ + size_t priv_offset; /* Key offset from start */ + size_t priv_length; /* Key bytes */ + size_t pub_offset; /* Pubkey offset */ + size_t pub_length; /* Pubkey bytes */ +} ML_COMMON_PKCS8_FMT; + +typedef struct { + const ML_COMMON_SPKI_FMT *spkifmt; + const ML_COMMON_PKCS8_FMT *p8fmt; +} ML_COMMON_CODEC; + +typedef struct { + const ML_COMMON_PKCS8_FMT *fmt; + int pref; +} ML_COMMON_PKCS8_FMT_PREF; + +ML_COMMON_PKCS8_FMT_PREF * +ossl_ml_common_pkcs8_fmt_order(const char *algorithm_name, + const ML_COMMON_PKCS8_FMT *p8fmt, + const char *direction, const char *formats); +#endif |