xref: /freebsd/crypto/openssl/providers/implementations/encode_decode/ml_common_codecs.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery  * Copyright 2025 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 #ifndef PROV_ML_COMMON_CODECS_H
11*e7be843bSPierre Pronchery # define PROV_ML_COMMON_CODECS_H
12*e7be843bSPierre Pronchery # pragma once
13*e7be843bSPierre Pronchery 
14*e7be843bSPierre Pronchery #  include <openssl/e_os2.h>
15*e7be843bSPierre Pronchery #  include "crypto/ml_dsa.h"
16*e7be843bSPierre Pronchery #  include "prov/provider_ctx.h"
17*e7be843bSPierre Pronchery 
18*e7be843bSPierre Pronchery  /*-
19*e7be843bSPierre Pronchery   * The DER ASN.1 encoding of ML-DSA and ML-KEM public keys prepends 22 bytes
20*e7be843bSPierre Pronchery   * to the encoded public key:
21*e7be843bSPierre Pronchery   *
22*e7be843bSPierre Pronchery   * - 4 byte outer sequence tag and length
23*e7be843bSPierre Pronchery   * -  2 byte algorithm sequence tag and length
24*e7be843bSPierre Pronchery   * -    2 byte algorithm OID tag and length
25*e7be843bSPierre Pronchery   * -      9 byte algorithm OID (from NIST CSOR OID arc)
26*e7be843bSPierre Pronchery   * -  4 byte bit string tag and length
27*e7be843bSPierre Pronchery   * -    1 bitstring lead byte
28*e7be843bSPierre Pronchery   */
29*e7be843bSPierre Pronchery #  define ML_COMMON_SPKI_OVERHEAD   22
30*e7be843bSPierre Pronchery typedef struct {
31*e7be843bSPierre Pronchery     const uint8_t asn1_prefix[ML_COMMON_SPKI_OVERHEAD];
32*e7be843bSPierre Pronchery } ML_COMMON_SPKI_FMT;
33*e7be843bSPierre Pronchery 
34*e7be843bSPierre Pronchery /*-
35*e7be843bSPierre Pronchery * For each parameter set we support a few PKCS#8 input formats, three
36*e7be843bSPierre Pronchery  * corresponding to the "either or both" variants of:
37*e7be843bSPierre Pronchery  *
38*e7be843bSPierre Pronchery  *  ML-DSA-PrivateKey ::= CHOICE {
39*e7be843bSPierre Pronchery  *    seed [0] IMPLICIT OCTET STRING (SIZE (32)),
40*e7be843bSPierre Pronchery  *    expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)),
41*e7be843bSPierre Pronchery  *    both SEQUENCE {
42*e7be843bSPierre Pronchery  *      seed OCTET STRING (SIZE (32)),
43*e7be843bSPierre Pronchery  *      expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)) } }
44*e7be843bSPierre Pronchery  *
45*e7be843bSPierre Pronchery  *  ML-KEM-PrivateKey ::= CHOICE {
46*e7be843bSPierre Pronchery  *    seed [0] IMPLICIT OCTET STRING (SIZE (64)),
47*e7be843bSPierre Pronchery  *    expandedKey OCTET STRING (SIZE (1632 | 2400 | 3168)),
48*e7be843bSPierre Pronchery  *    both SEQUENCE {
49*e7be843bSPierre Pronchery  *      seed OCTET STRING (SIZE (64)),
50*e7be843bSPierre Pronchery  *      expandedKey OCTET STRING SIZE ((1632 | 2400 | 3168)) } }
51*e7be843bSPierre Pronchery  *
52*e7be843bSPierre Pronchery  * one more for a historical OQS encoding:
53*e7be843bSPierre Pronchery  *
54*e7be843bSPierre Pronchery  * - OQS private + public key: OCTET STRING
55*e7be843bSPierre Pronchery  *   (The public key is ignored, just as with PKCS#8 v2.)
56*e7be843bSPierre Pronchery  *
57*e7be843bSPierre Pronchery  * and two more that are the minimal IETF non-ASN.1 seed encoding:
58*e7be843bSPierre Pronchery  *
59*e7be843bSPierre Pronchery  * - Bare seed (just the 32 or 64 bytes)
60*e7be843bSPierre Pronchery  * - Bare priv (just the key bytes)
61*e7be843bSPierre Pronchery  *
62*e7be843bSPierre Pronchery  * A length of zero means that particular field is absent.
63*e7be843bSPierre Pronchery  *
64*e7be843bSPierre Pronchery  * The p8_shift is 0 when the top-level tag+length occupy four bytes, 2 when
65*e7be843bSPierre Pronchery  * they occupy two by†es, and 4 when no tag is used at all.
66*e7be843bSPierre Pronchery  */
67*e7be843bSPierre Pronchery #define NUM_PKCS8_FORMATS   6
68*e7be843bSPierre Pronchery 
69*e7be843bSPierre Pronchery typedef struct {
70*e7be843bSPierre Pronchery     const char *p8_name;    /* Format name */
71*e7be843bSPierre Pronchery     size_t p8_bytes;        /* Total P8 encoding length */
72*e7be843bSPierre Pronchery     int    p8_shift;        /* 4 - (top-level tag + len) */
73*e7be843bSPierre Pronchery     uint32_t p8_magic;      /* The tag + len value */
74*e7be843bSPierre Pronchery     uint16_t seed_magic;    /* Interior tag + len for the seed */
75*e7be843bSPierre Pronchery     size_t seed_offset;     /* Seed offset from start */
76*e7be843bSPierre Pronchery     size_t seed_length;     /* Seed bytes */
77*e7be843bSPierre Pronchery     uint32_t priv_magic;    /* Interior tag + len for the key */
78*e7be843bSPierre Pronchery     size_t priv_offset;     /* Key offset from start */
79*e7be843bSPierre Pronchery     size_t priv_length;     /* Key bytes */
80*e7be843bSPierre Pronchery     size_t pub_offset;      /* Pubkey offset */
81*e7be843bSPierre Pronchery     size_t pub_length;      /* Pubkey bytes */
82*e7be843bSPierre Pronchery } ML_COMMON_PKCS8_FMT;
83*e7be843bSPierre Pronchery 
84*e7be843bSPierre Pronchery typedef struct {
85*e7be843bSPierre Pronchery     const ML_COMMON_SPKI_FMT *spkifmt;
86*e7be843bSPierre Pronchery     const ML_COMMON_PKCS8_FMT *p8fmt;
87*e7be843bSPierre Pronchery } ML_COMMON_CODEC;
88*e7be843bSPierre Pronchery 
89*e7be843bSPierre Pronchery typedef struct {
90*e7be843bSPierre Pronchery     const ML_COMMON_PKCS8_FMT *fmt;
91*e7be843bSPierre Pronchery     int pref;
92*e7be843bSPierre Pronchery } ML_COMMON_PKCS8_FMT_PREF;
93*e7be843bSPierre Pronchery 
94*e7be843bSPierre Pronchery ML_COMMON_PKCS8_FMT_PREF *
95*e7be843bSPierre Pronchery ossl_ml_common_pkcs8_fmt_order(const char *algorithm_name,
96*e7be843bSPierre Pronchery                                const ML_COMMON_PKCS8_FMT *p8fmt,
97*e7be843bSPierre Pronchery                                const char *direction, const char *formats);
98*e7be843bSPierre Pronchery #endif
99