Skip to content

Commit 7f64587

Browse files
committed
fix: BIT STRING unused bits in PKCS#8 publicKey
1 parent e61f90d commit 7f64587

12 files changed

Lines changed: 551 additions & 50 deletions

File tree

‎ChangeLog.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
cache rows and columns, so an image written by a build with different
3939
dimensions is rejected with `CACHE_MATCH_ERROR` instead of being copied in.
4040
A saved cache from an older release cannot be restored by this one.
41+
* **BREAKING (RFC 5958)**: The `publicKey` field of PKCS#8 v2 private keys (`OneAsymmetricKey`) for Ed25519, Ed448, X25519, ML-DSA and Falcon is a BIT STRING and now carries its unused-bits byte, so keys written by wolfSSL load in ring and other conformant parsers, and wolfSSL reads theirs. X25519 key values are still stored in reversed byte order, a separate bug, so X25519 PKCS#8 keys do not yet interoperate. Keys written by earlier wolfSSL still decode, but earlier wolfSSL cannot read keys written by this release. To write keys that every version reads, use `wc_Ed25519PrivateKeyToDer` and the other `*PrivateKeyToDer` functions, which omit `publicKey`. `WC_MLDSA_44/65/87_BOTH_KEY_DER_SIZE` and `CURVE25519_MAX_KEY_TO_DER_SZ` each grow by one byte, so applications that size buffers from them must be recompiled. A non-empty `publicKey` that matches neither form is now rejected with `ASN_PARSE_E`; an empty one is still treated as absent. by @MarkAtwood (PR 11674)
4142

4243
## Post-Quantum Cryptography (PQC)
4344

‎doc/dox_comments/header_files-ja/asn_public.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
14141414
/*!
14151415
\ingroup ASN
14161416
1417-
\brief この関数は、Curve25519キーをDER形式にエンコードします。秘密鍵、公開鍵、または両方をエンコードできます。
1417+
\brief この関数は、Curve25519キーをDER形式にエンコードします。秘密鍵、公開鍵、または両方をエンコードできます。両方が設定されている場合、[1] publicKeyはRFC 5958に従いBIT STRINGとして書き込まれるため、この変更より前のwolfSSLリリースでは読み込めません。wc_Curve25519PrivateKeyToDer()はこのフィールドを出力しません。
14181418
14191419
\return >0 成功、DERエンコーディングの長さ
14201420
\return BAD_FUNC_ARG keyまたはoutputがnullの場合に返されます

‎doc/dox_comments/header_files-ja/wc_mldsa.h‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ int wc_MlDsaKey_PublicKeyToDer(wc_MlDsaKey* key, byte* output,
757757
/*!
758758
\ingroup ML_DSA
759759
760-
\brief ML-DSA鍵ペア(公開鍵+秘密鍵)をPKCS#8 OneAsymmetricKey構造としてDERにエンコードします。必要なバッファサイズを問い合わせるには、outputにNULLを渡してください。
760+
\brief ML-DSA鍵ペア(公開鍵+秘密鍵)をPKCS#8 OneAsymmetricKey構造としてDERにエンコードします。必要なバッファサイズを問い合わせるには、outputにNULLを渡してください。[1] publicKeyはRFC 5958に従いBIT STRINGとして書き込まれるため、この変更より前のwolfSSLリリースでは読み込めません。wc_MlDsaKey_PrivateKeyToDer()はこのフィールドを出力しません。
761761
762762
\return 成功した場合、エンコードされたDERのサイズ(バイト単位)を返します。
763763
\return BAD_FUNC_ARG keyがNULLの場合、またはパラメータセットが選択されていない場合に返されます。
@@ -777,10 +777,12 @@ int wc_MlDsaKey_KeyToDer(wc_MlDsaKey* key, byte* output, word32 inLen);
777777
/*!
778778
\ingroup ML_DSA
779779
780-
\brief ML-DSA秘密鍵をDERにエンコードします。FIPS 204では秘密鍵のエンコードに公開鍵の要素が含まれるため、この関数は現在wc_MlDsaKey_KeyToDer()のエイリアスであり、他のアルゴリズムとのAPIの一貫性のために維持されています。
780+
\brief ML-DSA秘密鍵を、[1] publicKeyフィールドを含まないPKCS#8 OneAsymmetricKey v1構造としてDERにエンコードします。この出力は以前のwolfSSLリリースでも読み込めます。必要なバッファサイズを問い合わせるには、outputにNULLを渡してください。
781781
782782
\return 成功した場合、エンコードされたDERのサイズ(バイト単位)を返します。
783-
\return wc_MlDsaKey_KeyToDer()から引き継がれたエラーコードが返されます。
783+
\return BAD_FUNC_ARG keyがNULLの場合、秘密鍵が設定されていない場合、パラメータセットが選択されていない場合、またはoutputがNULLでなくinLenが小さすぎる場合に返されます。
784+
\return BUFFER_E outputがNULLでなく、inLenが0の場合に返されます。
785+
\return MEMORY_E 動的メモリの割り当てに失敗した場合に返されます。
784786
785787
\param [in] key 秘密鍵を保持するwc_MlDsaKeyへのポインタ。
786788
\param [out] output DERエンコードを受け取るバッファ。サイズを問い合わせる場合はNULL。

‎doc/dox_comments/header_files/asn_public.h‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2798,7 +2798,10 @@ int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 outLen
27982798
\ingroup ASN
27992799
28002800
\brief This function encodes a Curve25519 key to DER format. It can encode
2801-
either a private key, a public key, or both.
2801+
either a private key, a public key, or both. When both are set, the
2802+
[1] publicKey is written as an RFC 5958 BIT STRING, which wolfSSL
2803+
releases before this change cannot read;
2804+
wc_Curve25519PrivateKeyToDer() omits it.
28022805
28032806
\return >0 Success, length of DER encoding
28042807
\return BAD_FUNC_ARG Returns if key or output is null
@@ -2917,6 +2920,9 @@ int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
29172920
/*!
29182921
\ingroup Ed25519
29192922
\brief Encodes Ed25519 key to DER format.
2923+
The [1] publicKey is written as an RFC 5958 BIT STRING, which
2924+
wolfSSL releases before this change cannot read; wc_Ed25519PrivateKeyToDer()
2925+
omits it.
29202926
29212927
\return Size on success
29222928
\return negative on error
@@ -3077,6 +3083,9 @@ int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
30773083
/*!
30783084
\ingroup Ed448
30793085
\brief Encodes Ed448 key to DER format.
3086+
The [1] publicKey is written as an RFC 5958 BIT STRING, which
3087+
wolfSSL releases before this change cannot read; wc_Ed448PrivateKeyToDer()
3088+
omits it.
30803089
30813090
\return Size on success
30823091
\return negative on error

‎doc/dox_comments/header_files/falcon.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,9 @@ int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
549549
550550
\brief Encodes a Falcon private key (with its public key) as a DER/ASN.1
551551
(PKCS#8) structure. Pass a NULL output to query the required length.
552+
The [1] publicKey is written as an RFC 5958 BIT STRING, which
553+
wolfSSL releases before this change cannot read; wc_Falcon_PrivateKeyToDer()
554+
omits it.
552555
553556
\return Number of bytes written (or required, if output is NULL) on success.
554557
\return BAD_FUNC_ARG or BUFFER_E on error.

‎doc/dox_comments/header_files/wc_mldsa.h‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,9 @@ int wc_MlDsaKey_PublicKeyToDer(wc_MlDsaKey* key, byte* output,
954954
\brief Encodes an ML-DSA key pair (public + private) to DER as a
955955
PKCS#8 OneAsymmetricKey structure. Pass NULL as output to query
956956
the required buffer size.
957+
The [1] publicKey is written as an RFC 5958 BIT STRING, which
958+
wolfSSL releases before this change cannot read;
959+
wc_MlDsaKey_PrivateKeyToDer() omits it.
957960
958961
\return Size of the encoded DER in bytes on success.
959962
\return BAD_FUNC_ARG if key is NULL or no parameter set is
@@ -975,13 +978,17 @@ int wc_MlDsaKey_KeyToDer(wc_MlDsaKey* key, byte* output, word32 inLen);
975978
/*!
976979
\ingroup ML_DSA
977980
978-
\brief Encodes the ML-DSA private key to DER. Per FIPS 204 the
979-
private key encoding includes the public component, so this
980-
function is currently an alias of wc_MlDsaKey_KeyToDer() kept for
981-
API parity with other algorithms.
981+
\brief Encodes the ML-DSA private key to DER as a PKCS#8
982+
OneAsymmetricKey v1 structure with no [1] publicKey field. Earlier
983+
wolfSSL releases can read this output. Pass NULL as output to query
984+
the required buffer size.
982985
983986
\return Size of the encoded DER in bytes on success.
984-
\return Inherited error codes from wc_MlDsaKey_KeyToDer().
987+
\return BAD_FUNC_ARG if key is NULL, the private key has not been
988+
set, no parameter set is selected, or output is non-NULL and inLen
989+
is too small.
990+
\return BUFFER_E if output is non-NULL and inLen is 0.
991+
\return MEMORY_E if dynamic memory allocation fails.
985992
986993
\param [in] key Pointer to a wc_MlDsaKey with the private key.
987994
\param [out] output Buffer that receives the DER encoding, or

0 commit comments

Comments
 (0)