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