File: ml_common_codecs.h

package info (click to toggle)
openssl 3.5.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 142,688 kB
  • sloc: ansic: 672,420; perl: 233,226; asm: 6,546; sh: 1,569; pascal: 975; python: 596; makefile: 538; lisp: 35; ruby: 16; cpp: 10; sed: 6
file content (98 lines) | stat: -rw-r--r-- 3,239 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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