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