1#
2# This file is part of pyasn1-modules software.
3#
4# Created by Russ Housley.
5#
6# Copyright (c) 2019, Vigil Security, LLC
7# License: http://snmplabs.com/pyasn1/license.html
8#
9# PKCS #5: Password-Based Cryptography Specification, Version 2.1
10#
11# ASN.1 source from:
12# https://www.rfc-editor.org/rfc/rfc8018.txt
13#
14
15from pyasn1.type import constraint
16from pyasn1.type import namedtype
17from pyasn1.type import namedval
18from pyasn1.type import univ
19
20from pyasn1_modules import rfc3565
21from pyasn1_modules import rfc5280
22
23MAX = float('inf')
24
25def _OID(*components):
26    output = []
27    for x in tuple(components):
28        if isinstance(x, univ.ObjectIdentifier):
29            output.extend(list(x))
30        else:
31            output.append(int(x))
32
33    return univ.ObjectIdentifier(output)
34
35
36# Import from RFC 3565
37
38AES_IV = rfc3565.AES_IV
39
40
41# Import from RFC 5280
42
43AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
44
45
46# Basic object identifiers
47
48nistAlgorithms = _OID(2, 16, 840, 1, 101, 3, 4)
49
50aes = _OID(nistAlgorithms, 1)
51
52oiw = _OID(1, 3, 14)
53
54rsadsi = _OID(1, 2, 840, 113549)
55
56pkcs = _OID(rsadsi, 1)
57
58digestAlgorithm = _OID(rsadsi, 2)
59
60encryptionAlgorithm = _OID(rsadsi, 3)
61
62pkcs_5 = _OID(pkcs, 5)
63
64
65
66# HMAC object identifiers
67
68id_hmacWithSHA1 = _OID(digestAlgorithm, 7)
69
70id_hmacWithSHA224 = _OID(digestAlgorithm, 8)
71
72id_hmacWithSHA256 = _OID(digestAlgorithm, 9)
73
74id_hmacWithSHA384 = _OID(digestAlgorithm, 10)
75
76id_hmacWithSHA512 = _OID(digestAlgorithm, 11)
77
78id_hmacWithSHA512_224 = _OID(digestAlgorithm, 12)
79
80id_hmacWithSHA512_256 = _OID(digestAlgorithm, 13)
81
82
83# PBES1 object identifiers
84
85pbeWithMD2AndDES_CBC = _OID(pkcs_5, 1)
86
87pbeWithMD2AndRC2_CBC = _OID(pkcs_5, 4)
88
89pbeWithMD5AndDES_CBC = _OID(pkcs_5, 3)
90
91pbeWithMD5AndRC2_CBC = _OID(pkcs_5, 6)
92
93pbeWithSHA1AndDES_CBC = _OID(pkcs_5, 10)
94
95pbeWithSHA1AndRC2_CBC = _OID(pkcs_5, 11)
96
97
98# Supporting techniques object identifiers
99
100desCBC = _OID(oiw, 3, 2, 7)
101
102des_EDE3_CBC = _OID(encryptionAlgorithm, 7)
103
104rc2CBC = _OID(encryptionAlgorithm, 2)
105
106rc5_CBC_PAD = _OID(encryptionAlgorithm, 9)
107
108aes128_CBC_PAD = _OID(aes, 2)
109
110aes192_CBC_PAD = _OID(aes, 22)
111
112aes256_CBC_PAD = _OID(aes, 42)
113
114
115# PBES1
116
117class PBEParameter(univ.Sequence):
118    pass
119
120PBEParameter.componentType = namedtype.NamedTypes(
121    namedtype.NamedType('salt', univ.OctetString().subtype(
122        subtypeSpec=constraint.ValueSizeConstraint(8, 8))),
123    namedtype.NamedType('iterationCount', univ.Integer())
124)
125
126
127# PBES2
128
129id_PBES2 = _OID(pkcs_5, 13)
130
131
132class PBES2_params(univ.Sequence):
133    pass
134
135PBES2_params.componentType = namedtype.NamedTypes(
136    namedtype.NamedType('keyDerivationFunc', AlgorithmIdentifier()),
137    namedtype.NamedType('encryptionScheme', AlgorithmIdentifier())
138)
139
140
141# PBMAC1
142
143id_PBMAC1 = _OID(pkcs_5, 14)
144
145
146class PBMAC1_params(univ.Sequence):
147    pass
148
149PBMAC1_params.componentType = namedtype.NamedTypes(
150    namedtype.NamedType('keyDerivationFunc', AlgorithmIdentifier()),
151    namedtype.NamedType('messageAuthScheme', AlgorithmIdentifier())
152)
153
154
155# PBKDF2
156
157id_PBKDF2 = _OID(pkcs_5, 12)
158
159
160algid_hmacWithSHA1 = AlgorithmIdentifier()
161algid_hmacWithSHA1['algorithm'] = id_hmacWithSHA1
162algid_hmacWithSHA1['parameters'] = univ.Null("")
163
164
165class PBKDF2_params(univ.Sequence):
166    pass
167
168PBKDF2_params.componentType = namedtype.NamedTypes(
169    namedtype.NamedType('salt', univ.Choice(componentType=namedtype.NamedTypes(
170        namedtype.NamedType('specified', univ.OctetString()),
171        namedtype.NamedType('otherSource', AlgorithmIdentifier())
172    ))),
173    namedtype.NamedType('iterationCount', univ.Integer().subtype(
174        subtypeSpec=constraint.ValueRangeConstraint(1, MAX))),
175    namedtype.OptionalNamedType('keyLength', univ.Integer().subtype(
176        subtypeSpec=constraint.ValueRangeConstraint(1, MAX))),
177    namedtype.DefaultedNamedType('prf', algid_hmacWithSHA1)
178)
179
180
181# RC2 CBC algorithm parameter
182
183class RC2_CBC_Parameter(univ.Sequence):
184    pass
185
186RC2_CBC_Parameter.componentType = namedtype.NamedTypes(
187    namedtype.OptionalNamedType('rc2ParameterVersion', univ.Integer()),
188    namedtype.NamedType('iv', univ.OctetString().subtype(
189        subtypeSpec=constraint.ValueSizeConstraint(8, 8)))
190)
191
192
193# RC5 CBC algorithm parameter
194
195class RC5_CBC_Parameters(univ.Sequence):
196    pass
197
198RC5_CBC_Parameters.componentType = namedtype.NamedTypes(
199    namedtype.NamedType('version',
200        univ.Integer(namedValues=namedval.NamedValues(('v1_0', 16))).subtype(
201            subtypeSpec=constraint.SingleValueConstraint(16))),
202    namedtype.NamedType('rounds',
203        univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(8, 127))),
204    namedtype.NamedType('blockSizeInBits',
205        univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(64, 128))),
206    namedtype.OptionalNamedType('iv', univ.OctetString())
207)
208
209
210# Initialization Vector for AES: OCTET STRING (SIZE(16))
211
212class AES_IV(univ.OctetString):
213    pass
214
215AES_IV.subtypeSpec = constraint.ValueSizeConstraint(16, 16)
216
217
218# Initialization Vector for DES: OCTET STRING (SIZE(8))
219
220class DES_IV(univ.OctetString):
221    pass
222
223DES_IV.subtypeSpec = constraint.ValueSizeConstraint(8, 8)
224
225
226# Update the Algorithm Identifier map
227
228_algorithmIdentifierMapUpdate = {
229    # PBKDF2-PRFs
230    id_hmacWithSHA1: univ.Null(),
231    id_hmacWithSHA224: univ.Null(),
232    id_hmacWithSHA256: univ.Null(),
233    id_hmacWithSHA384: univ.Null(),
234    id_hmacWithSHA512: univ.Null(),
235    id_hmacWithSHA512_224: univ.Null(),
236    id_hmacWithSHA512_256: univ.Null(),
237    # PBES1Algorithms
238    pbeWithMD2AndDES_CBC: PBEParameter(),
239    pbeWithMD2AndRC2_CBC: PBEParameter(),
240    pbeWithMD5AndDES_CBC: PBEParameter(),
241    pbeWithMD5AndRC2_CBC: PBEParameter(),
242    pbeWithSHA1AndDES_CBC: PBEParameter(),
243    pbeWithSHA1AndRC2_CBC: PBEParameter(),
244    # PBES2Algorithms
245    id_PBES2: PBES2_params(),
246    # PBES2-KDFs
247    id_PBKDF2: PBKDF2_params(),
248    # PBMAC1Algorithms
249    id_PBMAC1: PBMAC1_params(),
250    # SupportingAlgorithms
251    desCBC: DES_IV(),
252    des_EDE3_CBC: DES_IV(),
253    rc2CBC: RC2_CBC_Parameter(),
254    rc5_CBC_PAD: RC5_CBC_Parameters(),
255    aes128_CBC_PAD: AES_IV(),
256    aes192_CBC_PAD: AES_IV(),
257    aes256_CBC_PAD: AES_IV(),
258}
259
260rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate)
261