Path: blob/main/crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h
48383 views
/*1* Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#ifndef PROV_ML_COMMON_CODECS_H10# define PROV_ML_COMMON_CODECS_H11# pragma once1213# include <openssl/e_os2.h>14# include "crypto/ml_dsa.h"15# include "prov/provider_ctx.h"1617/*-18* The DER ASN.1 encoding of ML-DSA and ML-KEM public keys prepends 22 bytes19* to the encoded public key:20*21* - 4 byte outer sequence tag and length22* - 2 byte algorithm sequence tag and length23* - 2 byte algorithm OID tag and length24* - 9 byte algorithm OID (from NIST CSOR OID arc)25* - 4 byte bit string tag and length26* - 1 bitstring lead byte27*/28# define ML_COMMON_SPKI_OVERHEAD 2229typedef struct {30const uint8_t asn1_prefix[ML_COMMON_SPKI_OVERHEAD];31} ML_COMMON_SPKI_FMT;3233/*-34* For each parameter set we support a few PKCS#8 input formats, three35* corresponding to the "either or both" variants of:36*37* ML-DSA-PrivateKey ::= CHOICE {38* seed [0] IMPLICIT OCTET STRING (SIZE (32)),39* expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)),40* both SEQUENCE {41* seed OCTET STRING (SIZE (32)),42* expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)) } }43*44* ML-KEM-PrivateKey ::= CHOICE {45* seed [0] IMPLICIT OCTET STRING (SIZE (64)),46* expandedKey OCTET STRING (SIZE (1632 | 2400 | 3168)),47* both SEQUENCE {48* seed OCTET STRING (SIZE (64)),49* expandedKey OCTET STRING SIZE ((1632 | 2400 | 3168)) } }50*51* one more for a historical OQS encoding:52*53* - OQS private + public key: OCTET STRING54* (The public key is ignored, just as with PKCS#8 v2.)55*56* and two more that are the minimal IETF non-ASN.1 seed encoding:57*58* - Bare seed (just the 32 or 64 bytes)59* - Bare priv (just the key bytes)60*61* A length of zero means that particular field is absent.62*63* The p8_shift is 0 when the top-level tag+length occupy four bytes, 2 when64* they occupy two by†es, and 4 when no tag is used at all.65*/66#define NUM_PKCS8_FORMATS 66768typedef struct {69const char *p8_name; /* Format name */70size_t p8_bytes; /* Total P8 encoding length */71int p8_shift; /* 4 - (top-level tag + len) */72uint32_t p8_magic; /* The tag + len value */73uint16_t seed_magic; /* Interior tag + len for the seed */74size_t seed_offset; /* Seed offset from start */75size_t seed_length; /* Seed bytes */76uint32_t priv_magic; /* Interior tag + len for the key */77size_t priv_offset; /* Key offset from start */78size_t priv_length; /* Key bytes */79size_t pub_offset; /* Pubkey offset */80size_t pub_length; /* Pubkey bytes */81} ML_COMMON_PKCS8_FMT;8283typedef struct {84const ML_COMMON_SPKI_FMT *spkifmt;85const ML_COMMON_PKCS8_FMT *p8fmt;86} ML_COMMON_CODEC;8788typedef struct {89const ML_COMMON_PKCS8_FMT *fmt;90int pref;91} ML_COMMON_PKCS8_FMT_PREF;9293ML_COMMON_PKCS8_FMT_PREF *94ossl_ml_common_pkcs8_fmt_order(const char *algorithm_name,95const ML_COMMON_PKCS8_FMT *p8fmt,96const char *direction, const char *formats);97#endif9899100