Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Curve25519 generic keyparsing #8129

Merged
merged 5 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions doc/dox_comments/header_files/asn_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,219 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output,
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output,
word32 inLen, int with_AlgCurve, int comp);


/*!
\ingroup ASN

\brief This function decodes a Curve25519 private key (only) from a DER
encoded buffer

\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.

\param input Pointer to buffer containing DER encoded private key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer

\sa wc_Curve25519KeyDecode
\sa wc_Curve25519PublicKeyDecode

_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);

if (wc_Curve25519PrivateKeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding private key
}
\endcode
*/
bigbrett marked this conversation as resolved.
Show resolved Hide resolved
int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
bigbrett marked this conversation as resolved.
Show resolved Hide resolved
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN

\brief This function decodes a Curve25519 public key (only) from a DER
encoded buffer.

\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.

\param input Pointer to buffer containing DER encoded public key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer

\sa wc_Curve25519KeyDecode
\sa wc_Curve25519PrivateKeyDecode

_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);
if (wc_Curve25519PublicKeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding public key
}
\endcode
*/
int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN

\brief This function decodes a Curve25519 key from a DER encoded buffer. It
can decode either a private key, a public key, or both.

\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.

\param input Pointer to buffer containing DER encoded key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer

\sa wc_Curve25519PrivateKeyDecode
\sa wc_Curve25519PublicKeyDecode

_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);
if (wc_Curve25519KeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding key
}
\endcode
*/
int wc_Curve25519KeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN

\brief This function encodes a Curve25519 private key to DER format. If the
input key structure contains a public key, it will be ignored.

\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small

\param key Pointer to curve25519_key structure containing private key to
encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer

\sa wc_Curve25519KeyToDer
\sa wc_Curve25519PublicKeyToDer

_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519PrivateKeyToDer(&key, der, derSz);
\endcode
*/
int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output,
word32 inLen);

/*!
\ingroup ASN

\brief This function encodes a Curve25519 public key to DER format. If the
input key structure contains a private key, it will be ignored.

\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small

\param key Pointer to curve25519_key structure containing public key to
encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer
\param withAlg Whether to include algorithm identifier in the DER encoding

\sa wc_Curve25519KeyToDer
\sa wc_Curve25519PrivateKeyToDer

_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519PublicKeyToDer(&key, der, derSz, 1);
\endcode
*/
int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
int withAlg);

/*!
\ingroup ASN

\brief This function encodes a Curve25519 key to DER format. It can encode
either a private key, a public key, or both.

\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small

\param key Pointer to curve25519_key structure containing key to encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer
\param withAlg Whether to include algorithm identifier in the DER encoding

\sa wc_Curve25519PrivateKeyToDer
\sa wc_Curve25519PublicKeyToDer

_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519KeyToDer(&key, der, derSz, 1);
\endcode
*/
int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen,
int withAlg);

/*!
\ingroup ASN

Expand Down
106 changes: 106 additions & 0 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -35661,6 +35661,55 @@ int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
}
return ret;
}

/* Decode Curve25519 key from DER format - can handle private only,
* public only, or private+public key pairs.
* return 0 on success, negative on error */
int wc_Curve25519KeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz)
{
int ret;
byte privKey[CURVE25519_KEYSIZE];
byte pubKey[CURVE25519_PUB_KEY_SIZE];
bigbrett marked this conversation as resolved.
Show resolved Hide resolved
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;

/* sanity check */
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
return BAD_FUNC_ARG;
}

/* Try to decode as private key first (may include public) */
ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
pubKey, &pubKeyLen, X25519k);

if (ret == 0) {
/* Successfully decoded private key */
if (pubKeyLen > 0) {
/* Have both private and public */
ret = wc_curve25519_import_private_raw(privKey, privKeyLen,
pubKey, pubKeyLen, key);
}
else {
/* Private only */
ret = wc_curve25519_import_private(privKey, privKeyLen, key);
}
}
else {
/* Try decoding as public key */
*inOutIdx = 0; /* Reset index */
pubKeyLen = CURVE25519_KEYSIZE;
ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
pubKey, &pubKeyLen, X25519k);
if (ret == 0) {
/* Successfully decoded public key */
ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
}
}

return ret;
}

#endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */


Expand Down Expand Up @@ -35868,6 +35917,63 @@ int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
}
return ret;
}

/* Export Curve25519 key to DER format - handles private only, public only,
* or private+public key pairs based on what's set in the key structure.
* Returns length written on success, negative on error */
int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen, int withAlg)
{
int ret;
byte privKey[CURVE25519_KEYSIZE];
byte pubKey[CURVE25519_PUB_KEY_SIZE];
bigbrett marked this conversation as resolved.
Show resolved Hide resolved
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;

if (key == NULL) {
return BAD_FUNC_ARG;
}

/* Check what we have in the key structure */
if (key->privSet) {
/* Export private key to buffer */
ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
if (ret != 0) {
return ret;
}

if (key->pubSet) {
/* Export public key if available */
ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
if (ret != 0) {
return ret;
}
/* Export both private and public */
ret = SetAsymKeyDer(privKey, privKeyLen,
pubKey, pubKeyLen,
output, inLen, X25519k);
}
else {
/* Export private only */
ret = SetAsymKeyDer(privKey, privKeyLen,
NULL, 0,
output, inLen, X25519k);
}
}
else if (key->pubSet) {
/* Export public key only */
ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
if (ret == 0) {
ret = SetAsymKeyDerPublic(pubKey, pubKeyLen,
output, inLen, X25519k, withAlg);
}
}
else {
/* Neither public nor private key is set */
ret = BAD_FUNC_ARG;
}

return ret;
}
#endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */

#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
Expand Down
Loading
Loading