1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 #ifdef LTC_PBES
6
7 static const char * const s_oid_pbes2 = "1.2.840.113549.1.5.13";
8 static const char * const s_oid_pbkdf2 = "1.2.840.113549.1.5.12";
9
10 typedef struct {
11 const char *oid;
12 const char *id;
13 } oid_id_st;
14
15 static const oid_id_st s_hmac_oid_names[] = {
16 { "1.2.840.113549.2.7", "sha1" },
17 { "1.2.840.113549.2.8", "sha224" },
18 { "1.2.840.113549.2.9", "sha256" },
19 { "1.2.840.113549.2.10", "sha384" },
20 { "1.2.840.113549.2.11", "sha512" },
21 { "1.2.840.113549.2.12", "sha512-224" },
22 { "1.2.840.113549.2.13", "sha512-256" },
23 };
24
25 static const pbes_properties s_pbes2_default_types[] = {
26 { pkcs_5_alg2, "sha1", "des", 8, 0 },
27 { pkcs_5_alg2, "sha1", "rc2", 4, 0 },
28 { pkcs_5_alg2, "sha1", "3des", 24, 0 },
29 { pkcs_5_alg2, "sha1", "aes", 16, 0 },
30 { pkcs_5_alg2, "sha1", "aes", 24, 0 },
31 { pkcs_5_alg2, "sha1", "aes", 32, 0 },
32 };
33
34 typedef struct {
35 const pbes_properties *data;
36 const char* oid;
37 } oid_to_pbes;
38
39 static const oid_to_pbes s_pbes2_list[] = {
40 { &s_pbes2_default_types[0], "1.3.14.3.2.7" }, /* http://www.oid-info.com/get/1.3.14.3.2.7 desCBC */
41 { &s_pbes2_default_types[1], "1.2.840.113549.3.2" }, /* http://www.oid-info.com/get/1.2.840.113549.3.2 rc2CBC */
42 { &s_pbes2_default_types[2], "1.2.840.113549.3.7" }, /* http://www.oid-info.com/get/1.2.840.113549.3.7 des-EDE3-CBC */
43 { &s_pbes2_default_types[3], "2.16.840.1.101.3.4.1.2" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.2 aes128-CBC */
44 { &s_pbes2_default_types[4], "2.16.840.1.101.3.4.1.22" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.22 aes192-CBC */
45 { &s_pbes2_default_types[5], "2.16.840.1.101.3.4.1.42" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.42 aes256-CBC */
46 };
47
s_pbes2_from_oid(const ltc_asn1_list * cipher_oid,const ltc_asn1_list * hmac_oid,pbes_properties * res)48 static int s_pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list *hmac_oid, pbes_properties *res)
49 {
50 unsigned int i;
51 for (i = 0; i < sizeof(s_pbes2_list)/sizeof(s_pbes2_list[0]); ++i) {
52 if (pk_oid_cmp_with_asn1(s_pbes2_list[i].oid, cipher_oid) == CRYPT_OK) {
53 *res = *s_pbes2_list[i].data;
54 break;
55 }
56 }
57 if (res->c == NULL) return CRYPT_INVALID_CIPHER;
58 if (hmac_oid != NULL) {
59 for (i = 0; i < sizeof(s_hmac_oid_names)/sizeof(s_hmac_oid_names[0]); ++i) {
60 if (pk_oid_cmp_with_asn1(s_hmac_oid_names[i].oid, hmac_oid) == CRYPT_OK) {
61 res->h = s_hmac_oid_names[i].id;
62 return CRYPT_OK;
63 }
64 }
65 return CRYPT_INVALID_HASH;
66 }
67 return CRYPT_OK;
68 }
69
70
71 /**
72 Extract PBES2 parameters
73
74 @param s The start of the sequence with potential PBES2 parameters
75 @param res Pointer to where the extracted parameters should be stored
76 @return CRYPT_OK on success
77 */
pbes2_extract(const ltc_asn1_list * s,pbes_arg * res)78 int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res)
79 {
80 unsigned long klen;
81 ltc_asn1_list *lkdf, *lenc, *loptseq, *liter, *lhmac;
82 int err;
83
84 LTC_ARGCHK(s != NULL);
85 LTC_ARGCHK(res != NULL);
86
87 if ((err = pk_oid_cmp_with_asn1(s_oid_pbes2, s)) != CRYPT_OK) return err;
88
89 if (!LTC_ASN1_IS_TYPE(s->next, LTC_ASN1_SEQUENCE) ||
90 !LTC_ASN1_IS_TYPE(s->next->child, LTC_ASN1_SEQUENCE) ||
91 !LTC_ASN1_IS_TYPE(s->next->child->child, LTC_ASN1_OBJECT_IDENTIFIER) ||
92 !LTC_ASN1_IS_TYPE(s->next->child->child->next, LTC_ASN1_SEQUENCE) ||
93 !LTC_ASN1_IS_TYPE(s->next->child->next, LTC_ASN1_SEQUENCE) ||
94 !LTC_ASN1_IS_TYPE(s->next->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
95 return CRYPT_INVALID_PACKET;
96 }
97 /* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc:
98 * 0:d=0 hl=4 l= 380 cons: SEQUENCE
99 * 4:d=1 hl=2 l= 78 cons: SEQUENCE
100 * 6:d=2 hl=2 l= 9 prim: OBJECT :PBES2 (== 1.2.840.113549.1.5.13) (== *s)
101 * 17:d=2 hl=2 l= 65 cons: SEQUENCE
102 * 19:d=3 hl=2 l= 41 cons: SEQUENCE
103 * 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 (== *lkdf)
104 * 32:d=4 hl=2 l= 28 cons: SEQUENCE
105 * 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== res->salt)
106 * 44:d=5 hl=2 l= 2 prim: INTEGER :0800 (== res->iterations, *liter)
107 * 48:d=5 hl=2 l= 12 cons: SEQUENCE (== *loptseq - this sequence is optional, may be missing)
108 * 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 (== *lhmac)
109 * 60:d=6 hl=2 l= 0 prim: NULL
110 * 62:d=3 hl=2 l= 20 cons: SEQUENCE
111 * 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc (== *lenc)
112 * 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:B1404C4688DC9A5A
113 * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data)
114 */
115 lkdf = s->next->child->child;
116 lenc = s->next->child->next->child;
117
118 if ((err = pk_oid_cmp_with_asn1(s_oid_pbkdf2, lkdf)) != CRYPT_OK) return err;
119
120 if (!LTC_ASN1_IS_TYPE(lkdf->next, LTC_ASN1_SEQUENCE) ||
121 !LTC_ASN1_IS_TYPE(lkdf->next->child, LTC_ASN1_OCTET_STRING) ||
122 !LTC_ASN1_IS_TYPE(lkdf->next->child->next, LTC_ASN1_INTEGER)) {
123 return CRYPT_INVALID_PACKET;
124 }
125
126 liter = lkdf->next->child->next;
127 loptseq = liter->next;
128 res->salt = lkdf->next->child;
129 res->iterations = mp_get_int(liter->data);
130
131 /* There's an optional INTEGER keyLength after the iterations, skip that if it's there.
132 * c.f. RFC 2898 A.2 PBKDF2 */
133 if(LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_INTEGER)) {
134 loptseq = loptseq->next;
135 }
136
137 /* this sequence is optional */
138 lhmac = NULL;
139 if (LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_SEQUENCE) &&
140 LTC_ASN1_IS_TYPE(loptseq->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
141 lhmac = loptseq->child;
142 }
143 if ((err = s_pbes2_from_oid(lenc, lhmac, &res->type)) != CRYPT_OK) return err;
144
145 if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_OCTET_STRING)) {
146 /* 'NON-RC2'-CBC */
147 res->iv = lenc->next;
148 } else if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_SEQUENCE)) {
149 /* RC2-CBC is a bit special ...
150 *
151 * RC2-CBC-Parameter ::= SEQUENCE {
152 * rc2ParameterVersion INTEGER OPTIONAL,
153 * iv OCTET STRING (SIZE(8)) }
154 */
155 if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_INTEGER) &&
156 LTC_ASN1_IS_TYPE(lenc->next->child->next, LTC_ASN1_OCTET_STRING)) {
157 klen = mp_get_int(lenc->next->child->data);
158 res->iv = lenc->next->child->next;
159 /*
160 * Effective Key Bits Encoding
161 * 40 160
162 * 64 120
163 * 128 58
164 * b >= 256 b
165 */
166 switch (klen) {
167 case 160:
168 res->key_bits = 40;
169 break;
170 case 120:
171 res->key_bits = 64;
172 break;
173 case 58:
174 res->key_bits = 128;
175 break;
176 default:
177 /* We don't handle undefined Key Bits */
178 if (klen < 256) return CRYPT_INVALID_KEYSIZE;
179
180 res->key_bits = klen;
181 break;
182 }
183 } else if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_OCTET_STRING)) {
184 res->iv = lenc->next->child;
185 /*
186 * If the rc2ParameterVersion field is omitted, the "effective key bits"
187 * defaults to 32.
188 */
189 res->key_bits = 32;
190 } else {
191 return CRYPT_INVALID_PACKET;
192 }
193 }
194
195 return CRYPT_OK;
196 }
197
198 #endif
199