* 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;
size_t p8_bytes;
int p8_shift;
uint32_t p8_magic;
uint16_t seed_magic;
size_t seed_offset;
size_t seed_length;
uint32_t priv_magic;
size_t priv_offset;
size_t priv_length;
size_t pub_offset;
size_t pub_length;
} 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);
int ossl_bio_print_labeled_buf(BIO *out, const char *label,
const uint8_t *buf, size_t len);
#endif