Skip to content

Commit 2da3de5

Browse files
committed
add support for DH keys
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 2386ebf commit 2da3de5

File tree

12 files changed

+144
-4
lines changed

12 files changed

+144
-4
lines changed

src/headers/tomcrypt_pk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ int dh_get_groupsize(const dh_key *key);
141141

142142
int dh_export(unsigned char *out, unsigned long *outlen, int type, const dh_key *key);
143143
int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
144+
int dh_import_pkcs8(const unsigned char *in, unsigned long inlen,
145+
const password_ctx *pw_ctx, dh_key *key);
144146

145147
int dh_set_pg(const unsigned char *p, unsigned long plen,
146148
const unsigned char *g, unsigned long glen,

src/headers/tomcrypt_private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum ltc_oid_id {
2323
LTC_OID_EC_PRIMEF,
2424
LTC_OID_X25519,
2525
LTC_OID_ED25519,
26+
LTC_OID_DH,
2627
};
2728

2829
/*
@@ -335,7 +336,9 @@ int rsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, rsa_ke
335336
#ifdef LTC_MDH
336337
extern const ltc_dh_set_type ltc_dh_sets[];
337338

339+
int dh_init(dh_key *key);
338340
int dh_check_pubkey(const dh_key *key);
341+
int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key *key);
339342
#endif /* LTC_MDH */
340343

341344
/* ---- ECC Routines ---- */

src/misc/pem/pem_decode.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, password_ctx *pw_ctx)
9393
goto cleanup;
9494
}
9595
switch (pka) {
96+
#ifdef LTC_MDH
97+
case LTC_OID_DH:
98+
err = dh_import_pkcs8_asn1(alg_id, priv_key, &k->u.dh);
99+
k->id = LTC_PKA_DH;
100+
break;
101+
#endif
96102
#ifdef LTC_MDSA
97103
case LTC_OID_DSA:
98104
err = dsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.dsa);

src/pk/asn1/oid/pk_get.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ static const oid_table_entry pka_oids[] = {
1717
{ LTC_OID_EC_PRIMEF, LTC_PKA_EC, "1.2.840.10045.1.1" },
1818
{ LTC_OID_X25519, LTC_PKA_CURVE25519, "1.3.101.110" },
1919
{ LTC_OID_ED25519, LTC_PKA_CURVE25519, "1.3.101.112" },
20+
{ LTC_OID_DH, LTC_PKA_DH, "1.2.840.113549.1.3.1" },
2021
};
2122

2223
/*

src/pk/dh/dh.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,18 @@ int dh_get_groupsize(const dh_key *key)
224224
return mp_unsigned_bin_size(key->prime);
225225
}
226226

227+
/**
228+
Free the allocated ram for a DH key
229+
@param key The key which you wish to free
230+
*/
231+
int dh_init(dh_key *key)
232+
{
233+
int err;
234+
LTC_ARGCHK(key != NULL);
235+
if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
236+
return err;
237+
}
238+
return CRYPT_OK;
239+
}
240+
227241
#endif /* LTC_MDH */

src/pk/dh/dh_import.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
2222
LTC_ARGCHK(key != NULL);
2323

2424
/* init */
25-
if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
25+
if ((err = dh_init(key)) != CRYPT_OK) {
2626
return err;
2727
}
2828

src/pk/dh/dh_import_pkcs8.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
4+
#include "tomcrypt_private.h"
5+
6+
#ifdef LTC_MDH
7+
8+
int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key *key)
9+
{
10+
int err;
11+
12+
LTC_ARGCHK(key != NULL);
13+
14+
if (!alg_id->child ||
15+
!LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE) ||
16+
!LTC_ASN1_IS_TYPE(alg_id->child->next->child, LTC_ASN1_INTEGER) ||
17+
!LTC_ASN1_IS_TYPE(alg_id->child->next->child->next, LTC_ASN1_INTEGER)) {
18+
return CRYPT_PK_INVALID_TYPE;
19+
}
20+
21+
if ((err = dh_init(key)) != CRYPT_OK) {
22+
return err;
23+
}
24+
25+
if ((err = mp_copy(alg_id->child->next->child->data, key->prime)) != CRYPT_OK) {
26+
goto error;
27+
}
28+
if ((err = mp_copy(alg_id->child->next->child->next->data, key->base)) != CRYPT_OK) {
29+
goto error;
30+
}
31+
32+
if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) {
33+
goto error;
34+
}
35+
/* compute public key: y = (base ^ x) mod prime */
36+
if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
37+
goto error;
38+
}
39+
/* check public key */
40+
if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
41+
goto error;
42+
}
43+
key->type = PK_PRIVATE;
44+
45+
return CRYPT_OK;
46+
error:
47+
dh_free(key);
48+
return err;
49+
}
50+
51+
/**
52+
Import a DH key in PKCS#8 format
53+
@param in The packet to import from
54+
@param inlen It's length (octets)
55+
@param pw_ctx The password context when decrypting the private key
56+
@param key [out] Destination for newly imported key
57+
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
58+
*/
59+
int dh_import_pkcs8(const unsigned char *in, unsigned long inlen,
60+
const password_ctx *pw_ctx, dh_key *key)
61+
{
62+
int err;
63+
ltc_asn1_list *l = NULL;
64+
ltc_asn1_list *alg_id, *priv_key;
65+
enum ltc_oid_id pka;
66+
67+
LTC_ARGCHK(in != NULL);
68+
69+
if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) {
70+
return err;
71+
}
72+
if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
73+
goto LBL_DER_FREE;
74+
}
75+
if (pka != LTC_OID_DH) {
76+
err = CRYPT_INVALID_PACKET;
77+
goto LBL_DER_FREE;
78+
}
79+
80+
err = dh_import_pkcs8_asn1(alg_id, priv_key, key);
81+
82+
LBL_DER_FREE:
83+
der_free_sequence_flexi(l);
84+
return err;
85+
}
86+
87+
#endif /* LTC_MDH */

src/pk/dh/dh_set.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ int dh_set_pg(const unsigned char *p, unsigned long plen,
2626
LTC_ARGCHK(g != NULL);
2727
LTC_ARGCHK(ltc_mp.name != NULL);
2828

29-
if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
29+
if ((err = dh_init(key)) != CRYPT_OK) {
3030
return err;
3131
}
3232

@@ -58,9 +58,10 @@ int dh_set_pg_groupsize(int groupsize, dh_key *key)
5858
for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++);
5959
if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE;
6060

61-
if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
61+
if ((err = dh_init(key)) != CRYPT_OK) {
6262
return err;
6363
}
64+
6465
if ((err = mp_read_radix(key->base, ltc_dh_sets[i].base, 16)) != CRYPT_OK) { goto LBL_ERR; }
6566
if ((err = mp_read_radix(key->prime, ltc_dh_sets[i].prime, 16)) != CRYPT_OK) { goto LBL_ERR; }
6667

src/pk/dh/dh_set_pg_dhparam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh
2424
LTC_ARGCHK(dhparam != NULL);
2525
LTC_ARGCHK(dhparamlen > 0);
2626

27-
if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
27+
if ((err = dh_init(key)) != CRYPT_OK) {
2828
return err;
2929
}
3030
if ((err = der_decode_sequence_multi(dhparam, dhparamlen,

tests/pem/dh-encrypted.pk8

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIIBjTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI+JYkd4NoIU4CAggA
3+
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCNnY9OuYIvCurJu9sEYkz6BIIB
4+
MGzX4GwCvBQV/dOiy0PvbY443xkKZHPTtNbirE+9NLVVrTI7EUQv5UO5Xl0wVHje
5+
R4hADBzpIKAd0zjsGYfMQ6rEabIdO4R+UBKoibTgyOzt7Y5Ge/4+pYy14bMFeZ44
6+
6OaP6jXRsn1/DIi0mxcBo9eDfZX3FzgANWiDvFA2VWC+qEbsm4JBB8uDJ+aWtjyR
7+
mct/FXzGHwi+IGuPBzo9dIywisW4whmBwh1XpFBMxjmMLqWInuUailAkIARJ0w04
8+
GdGZ6HYlKmsTvAKv4WRK+EnwZ8JmBiVl6ulcX8k1zbrT2ElyBUCFneMktFKULE1l
9+
myVMuAQCuuGfWdquegqLOyvgK6S9p3wfVyzkney8qBN07WZHE+UUW8AQrZS6J5nS
10+
wSAjBu3wmDmDo7AWEQZFMK4=
11+
-----END ENCRYPTED PRIVATE KEY-----

0 commit comments

Comments
 (0)