ml_common_codecs.h 3.3 KB

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