1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file ec25519_export.c
7 Generic export of a Curve/Ed25519 key to a binary packet, Steffen Jaeckel
8 */
9
10 #ifdef LTC_CURVE25519
11
12 /**
13 Generic export of a Curve/Ed25519 key to a binary packet
14 @param out [out] The destination for the key
15 @param outlen [in/out] The max size and resulting size of the Ed25519 key
16 @param type Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
17 @param key The key you wish to export
18 @return CRYPT_OK if successful
19 */
ec25519_export(unsigned char * out,unsigned long * outlen,int which,const curve25519_key * key)20 int ec25519_export( unsigned char *out, unsigned long *outlen,
21 int which,
22 const curve25519_key *key)
23 {
24 int err, std;
25 const char* OID;
26 unsigned long oid[16], oidlen;
27 ltc_asn1_list alg_id[1];
28 unsigned char private_key[34];
29 unsigned long version, private_key_len = sizeof(private_key);
30
31 LTC_ARGCHK(out != NULL);
32 LTC_ARGCHK(outlen != NULL);
33 LTC_ARGCHK(key != NULL);
34
35 std = which & PK_STD;
36 which &= ~PK_STD;
37
38 if (which == PK_PRIVATE) {
39 if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
40
41 if (std == PK_STD) {
42 if ((err = pk_get_oid(key->algo, &OID)) != CRYPT_OK) {
43 return err;
44 }
45 oidlen = sizeof(oid)/sizeof(oid[0]);
46 if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
47 return err;
48 }
49
50 LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
51
52 /* encode private key as PKCS#8 */
53 if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
54 return err;
55 }
56
57 version = 0;
58 err = der_encode_sequence_multi(out, outlen,
59 LTC_ASN1_SHORT_INTEGER, 1uL, &version,
60 LTC_ASN1_SEQUENCE, 1uL, alg_id,
61 LTC_ASN1_OCTET_STRING, private_key_len, private_key,
62 LTC_ASN1_EOL, 0uL, NULL);
63 } else {
64 if (*outlen < sizeof(key->priv)) {
65 err = CRYPT_BUFFER_OVERFLOW;
66 } else {
67 XMEMCPY(out, key->priv, sizeof(key->priv));
68 err = CRYPT_OK;
69 }
70 *outlen = sizeof(key->priv);
71 }
72 } else {
73 if (std == PK_STD) {
74 /* encode public key as SubjectPublicKeyInfo */
75 err = x509_encode_subject_public_key_info(out, outlen, key->algo, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
76 } else {
77 if (*outlen < sizeof(key->pub)) {
78 err = CRYPT_BUFFER_OVERFLOW;
79 } else {
80 XMEMCPY(out, key->pub, sizeof(key->pub));
81 err = CRYPT_OK;
82 }
83 *outlen = sizeof(key->pub);
84 }
85 }
86
87 return err;
88 }
89
90 #endif
91