File: | s/lib/softoken/jpakesftk.c |
Warning: | line 54, column 13 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* This Source Code Form is subject to the terms of the Mozilla Public | |||
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
4 | ||||
5 | #include "seccomon.h" | |||
6 | #include "secerr.h" | |||
7 | #include "blapi.h" | |||
8 | #include "pkcs11i.h" | |||
9 | #include "softoken.h" | |||
10 | ||||
11 | static CK_RV | |||
12 | jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) | |||
13 | { | |||
14 | int err; | |||
15 | if (rv == SECSuccess) | |||
16 | return CKR_OK0x00000000UL; | |||
17 | err = PORT_GetErrorPORT_GetError_Util(); | |||
18 | switch (err) { | |||
19 | /* XXX: SEC_ERROR_INVALID_ARGS might be caused by invalid template | |||
20 | parameters. */ | |||
21 | case SEC_ERROR_INVALID_ARGS: | |||
22 | return invalidArgsMapping; | |||
23 | case SEC_ERROR_BAD_SIGNATURE: | |||
24 | return CKR_SIGNATURE_INVALID0x000000C0UL; | |||
25 | case SEC_ERROR_NO_MEMORY: | |||
26 | return CKR_HOST_MEMORY0x00000002UL; | |||
27 | } | |||
28 | return CKR_FUNCTION_FAILED0x00000006UL; | |||
29 | } | |||
30 | ||||
31 | /* If key is not NULL then the gx value will be stored as an attribute with | |||
32 | the type given by the gxAttrType parameter. */ | |||
33 | static CK_RV | |||
34 | jpake_Sign(PLArenaPool *arena, const PQGParams *pqg, HASH_HashType hashType, | |||
35 | const SECItem *signerID, const SECItem *x, | |||
36 | CK_NSS_JPAKEPublicValue *out) | |||
37 | { | |||
38 | SECItem gx, gv, r; | |||
39 | CK_RV crv; | |||
40 | ||||
41 | PORT_Assert(arena != NULL)((arena != ((void*)0))?((void)0):PR_Assert("arena != NULL","jpakesftk.c" ,41)); | |||
42 | ||||
43 | gx.data = NULL((void*)0); | |||
44 | gv.data = NULL((void*)0); | |||
45 | r.data = NULL((void*)0); | |||
46 | crv = jpake_mapStatus(JPAKE_Sign(arena, pqg, hashType, signerID, x, NULL((void*)0), | |||
47 | NULL((void*)0), &gx, &gv, &r), | |||
48 | CKR_MECHANISM_PARAM_INVALID0x00000071UL); | |||
49 | if (crv
| |||
50 | if ((out->pGX != NULL((void*)0) && out->ulGXLen >= gx.len) || | |||
51 | (out->pGV != NULL((void*)0) && out->ulGVLen >= gv.len) || | |||
52 | (out->pR != NULL((void*)0) && out->ulRLen >= r.len)) { | |||
53 | PORT_Memcpymemcpy(out->pGX, gx.data, gx.len); | |||
54 | PORT_Memcpymemcpy(out->pGV, gv.data, gv.len); | |||
| ||||
55 | PORT_Memcpymemcpy(out->pR, r.data, r.len); | |||
56 | out->ulGXLen = gx.len; | |||
57 | out->ulGVLen = gv.len; | |||
58 | out->ulRLen = r.len; | |||
59 | } else { | |||
60 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
61 | } | |||
62 | } | |||
63 | return crv; | |||
64 | } | |||
65 | ||||
66 | static CK_RV | |||
67 | jpake_Verify(PLArenaPool *arena, const PQGParams *pqg, | |||
68 | HASH_HashType hashType, const SECItem *signerID, | |||
69 | const CK_BYTE *peerIDData, CK_ULONG peerIDLen, | |||
70 | const CK_NSS_JPAKEPublicValue *publicValueIn) | |||
71 | { | |||
72 | SECItem peerID, gx, gv, r; | |||
73 | peerID.data = (unsigned char *)peerIDData; | |||
74 | peerID.len = peerIDLen; | |||
75 | gx.data = publicValueIn->pGX; | |||
76 | gx.len = publicValueIn->ulGXLen; | |||
77 | gv.data = publicValueIn->pGV; | |||
78 | gv.len = publicValueIn->ulGVLen; | |||
79 | r.data = publicValueIn->pR; | |||
80 | r.len = publicValueIn->ulRLen; | |||
81 | return jpake_mapStatus(JPAKE_Verify(arena, pqg, hashType, signerID, &peerID, | |||
82 | &gx, &gv, &r), | |||
83 | CKR_MECHANISM_PARAM_INVALID0x00000071UL); | |||
84 | } | |||
85 | ||||
86 | #define NUM_ELEM(x)(sizeof(x) / sizeof(x)[0]) (sizeof(x) / sizeof(x)[0]) | |||
87 | ||||
88 | /* If the template has the key type set, ensure that it was set to the correct | |||
89 | * value. If the template did not have the key type set, set it to the | |||
90 | * correct value. | |||
91 | */ | |||
92 | static CK_RV | |||
93 | jpake_enforceKeyType(SFTKObject *key, CK_KEY_TYPE keyType) | |||
94 | { | |||
95 | CK_RV crv; | |||
96 | SFTKAttribute *keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL); | |||
97 | if (keyTypeAttr != NULL((void*)0)) { | |||
98 | crv = *(CK_KEY_TYPE *)keyTypeAttr->attrib.pValue == keyType | |||
99 | ? CKR_OK0x00000000UL | |||
100 | : CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
101 | sftk_FreeAttribute(keyTypeAttr); | |||
102 | } else { | |||
103 | crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof keyType); | |||
104 | } | |||
105 | return crv; | |||
106 | } | |||
107 | ||||
108 | static CK_RV | |||
109 | jpake_MultipleSecItem2Attribute(SFTKObject *key, const SFTKItemTemplate *attrs, | |||
110 | size_t attrsCount) | |||
111 | { | |||
112 | size_t i; | |||
113 | ||||
114 | for (i = 0; i < attrsCount; ++i) { | |||
115 | CK_RV crv = sftk_forceAttribute(key, attrs[i].type, attrs[i].item->data, | |||
116 | attrs[i].item->len); | |||
117 | if (crv != CKR_OK0x00000000UL) | |||
118 | return crv; | |||
119 | } | |||
120 | return CKR_OK0x00000000UL; | |||
121 | } | |||
122 | ||||
123 | CK_RV | |||
124 | jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params *params, | |||
125 | SFTKObject *key) | |||
126 | { | |||
127 | CK_RV crv; | |||
128 | PQGParams pqg; | |||
129 | PLArenaPool *arena; | |||
130 | SECItem signerID; | |||
131 | SFTKItemTemplate templateAttrs[] = { | |||
132 | { CKA_PRIME0x00000130UL, &pqg.prime }, | |||
133 | { CKA_SUBPRIME0x00000131UL, &pqg.subPrime }, | |||
134 | { CKA_BASE0x00000132UL, &pqg.base }, | |||
135 | { CKA_NSS_JPAKE_SIGNERID((0x80000000UL | 0x4E534350) + 26), &signerID } | |||
136 | }; | |||
137 | SECItem x2, gx1, gx2; | |||
138 | const SFTKItemTemplate generatedAttrs[] = { | |||
139 | { CKA_NSS_JPAKE_X2((0x80000000UL | 0x4E534350) + 32), &x2 }, | |||
140 | { CKA_NSS_JPAKE_GX1((0x80000000UL | 0x4E534350) + 28), &gx1 }, | |||
141 | { CKA_NSS_JPAKE_GX2((0x80000000UL | 0x4E534350) + 29), &gx2 }, | |||
142 | }; | |||
143 | SECItem x1; | |||
144 | ||||
145 | PORT_Assert(params != NULL)((params != ((void*)0))?((void)0):PR_Assert("params != NULL", "jpakesftk.c",145)); | |||
| ||||
146 | PORT_Assert(key != NULL)((key != ((void*)0))?((void)0):PR_Assert("key != NULL","jpakesftk.c" ,146)); | |||
147 | ||||
148 | arena = PORT_NewArenaPORT_NewArena_Util(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE2048); | |||
149 | if (arena == NULL((void*)0)) | |||
150 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
151 | ||||
152 | crv = sftk_MultipleAttribute2SecItem(arena, key, templateAttrs, | |||
153 | NUM_ELEM(templateAttrs)(sizeof(templateAttrs) / sizeof(templateAttrs)[0])); | |||
154 | ||||
155 | if (crv == CKR_OK0x00000000UL && (signerID.data == NULL((void*)0) || signerID.len == 0)) | |||
156 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
157 | ||||
158 | /* generate x1, g^x1 and the proof of knowledge of x1 */ | |||
159 | if (crv
| |||
160 | x1.data = NULL((void*)0); | |||
161 | crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x1), | |||
162 | CKR_TEMPLATE_INCONSISTENT0x000000D1UL); | |||
163 | } | |||
164 | if (crv
| |||
165 | crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x1, ¶ms->gx1); | |||
166 | ||||
167 | /* generate x2, g^x2 and the proof of knowledge of x2 */ | |||
168 | if (crv == CKR_OK0x00000000UL) { | |||
169 | x2.data = NULL((void*)0); | |||
170 | crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x2), | |||
171 | CKR_TEMPLATE_INCONSISTENT0x000000D1UL); | |||
172 | } | |||
173 | if (crv == CKR_OK0x00000000UL) | |||
174 | crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2, ¶ms->gx2); | |||
175 | ||||
176 | /* Save the values needed for round 2 into CKA_VALUE */ | |||
177 | if (crv == CKR_OK0x00000000UL) { | |||
178 | gx1.data = params->gx1.pGX; | |||
179 | gx1.len = params->gx1.ulGXLen; | |||
180 | gx2.data = params->gx2.pGX; | |||
181 | gx2.len = params->gx2.ulGXLen; | |||
182 | crv = jpake_MultipleSecItem2Attribute(key, generatedAttrs, | |||
183 | NUM_ELEM(generatedAttrs)(sizeof(generatedAttrs) / sizeof(generatedAttrs)[0])); | |||
184 | } | |||
185 | ||||
186 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
187 | return crv; | |||
188 | } | |||
189 | ||||
190 | CK_RV | |||
191 | jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params *params, | |||
192 | SFTKObject *sourceKey, SFTKObject *key) | |||
193 | { | |||
194 | CK_RV crv; | |||
195 | PLArenaPool *arena; | |||
196 | PQGParams pqg; | |||
197 | SECItem signerID, x2, gx1, gx2; | |||
198 | SFTKItemTemplate sourceAttrs[] = { | |||
199 | { CKA_PRIME0x00000130UL, &pqg.prime }, | |||
200 | { CKA_SUBPRIME0x00000131UL, &pqg.subPrime }, | |||
201 | { CKA_BASE0x00000132UL, &pqg.base }, | |||
202 | { CKA_NSS_JPAKE_SIGNERID((0x80000000UL | 0x4E534350) + 26), &signerID }, | |||
203 | { CKA_NSS_JPAKE_X2((0x80000000UL | 0x4E534350) + 32), &x2 }, | |||
204 | { CKA_NSS_JPAKE_GX1((0x80000000UL | 0x4E534350) + 28), &gx1 }, | |||
205 | { CKA_NSS_JPAKE_GX2((0x80000000UL | 0x4E534350) + 29), &gx2 }, | |||
206 | }; | |||
207 | SECItem x2s, gx3, gx4; | |||
208 | const SFTKItemTemplate copiedAndGeneratedAttrs[] = { | |||
209 | { CKA_NSS_JPAKE_SIGNERID((0x80000000UL | 0x4E534350) + 26), &signerID }, | |||
210 | { CKA_PRIME0x00000130UL, &pqg.prime }, | |||
211 | { CKA_SUBPRIME0x00000131UL, &pqg.subPrime }, | |||
212 | { CKA_NSS_JPAKE_X2((0x80000000UL | 0x4E534350) + 32), &x2 }, | |||
213 | { CKA_NSS_JPAKE_X2S((0x80000000UL | 0x4E534350) + 33), &x2s }, | |||
214 | { CKA_NSS_JPAKE_GX1((0x80000000UL | 0x4E534350) + 28), &gx1 }, | |||
215 | { CKA_NSS_JPAKE_GX2((0x80000000UL | 0x4E534350) + 29), &gx2 }, | |||
216 | { CKA_NSS_JPAKE_GX3((0x80000000UL | 0x4E534350) + 30), &gx3 }, | |||
217 | { CKA_NSS_JPAKE_GX4((0x80000000UL | 0x4E534350) + 31), &gx4 } | |||
218 | }; | |||
219 | SECItem peerID; | |||
220 | ||||
221 | PORT_Assert(params != NULL)((params != ((void*)0))?((void)0):PR_Assert("params != NULL", "jpakesftk.c",221)); | |||
222 | PORT_Assert(sourceKey != NULL)((sourceKey != ((void*)0))?((void)0):PR_Assert("sourceKey != NULL" ,"jpakesftk.c",222)); | |||
223 | PORT_Assert(key != NULL)((key != ((void*)0))?((void)0):PR_Assert("key != NULL","jpakesftk.c" ,223)); | |||
224 | ||||
225 | arena = PORT_NewArenaPORT_NewArena_Util(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE2048); | |||
226 | if (arena == NULL((void*)0)) | |||
227 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
228 | ||||
229 | /* TODO: check CKK_NSS_JPAKE_ROUND1 */ | |||
230 | ||||
231 | crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs, | |||
232 | NUM_ELEM(sourceAttrs)(sizeof(sourceAttrs) / sizeof(sourceAttrs)[0])); | |||
233 | ||||
234 | /* Get the peer's ID out of the template and sanity-check it. */ | |||
235 | if (crv == CKR_OK0x00000000UL) | |||
236 | crv = sftk_Attribute2SecItem(arena, &peerID, key, | |||
237 | CKA_NSS_JPAKE_PEERID((0x80000000UL | 0x4E534350) + 27)); | |||
238 | if (crv == CKR_OK0x00000000UL && (peerID.data == NULL((void*)0) || peerID.len == 0)) | |||
239 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
240 | if (crv == CKR_OK0x00000000UL && SECITEM_CompareItemSECITEM_CompareItem_Util(&signerID, &peerID) == SECEqual) | |||
241 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
242 | ||||
243 | /* Verify zero-knowledge proofs for g^x3 and g^x4 */ | |||
244 | if (crv == CKR_OK0x00000000UL) | |||
245 | crv = jpake_Verify(arena, &pqg, hashType, &signerID, | |||
246 | peerID.data, peerID.len, ¶ms->gx3); | |||
247 | if (crv == CKR_OK0x00000000UL) | |||
248 | crv = jpake_Verify(arena, &pqg, hashType, &signerID, | |||
249 | peerID.data, peerID.len, ¶ms->gx4); | |||
250 | ||||
251 | /* Calculate the base and x2s for A=base^x2s */ | |||
252 | if (crv == CKR_OK0x00000000UL) { | |||
253 | SECItem s; | |||
254 | s.data = params->pSharedKey; | |||
255 | s.len = params->ulSharedKeyLen; | |||
256 | gx3.data = params->gx3.pGX; | |||
257 | gx3.len = params->gx3.ulGXLen; | |||
258 | gx4.data = params->gx4.pGX; | |||
259 | gx4.len = params->gx4.ulGXLen; | |||
260 | pqg.base.data = NULL((void*)0); | |||
261 | x2s.data = NULL((void*)0); | |||
262 | crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime, | |||
263 | &gx1, &gx3, &gx4, &pqg.base, | |||
264 | &x2, &s, &x2s), | |||
265 | CKR_MECHANISM_PARAM_INVALID0x00000071UL); | |||
266 | } | |||
267 | ||||
268 | /* Generate A=base^x2s and its zero-knowledge proof. */ | |||
269 | if (crv == CKR_OK0x00000000UL) | |||
270 | crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2s, ¶ms->A); | |||
271 | ||||
272 | /* Copy P and Q from the ROUND1 key to the ROUND2 key and save the values | |||
273 | needed for the final key material derivation into CKA_VALUE. */ | |||
274 | if (crv == CKR_OK0x00000000UL) | |||
275 | crv = sftk_forceAttribute(key, CKA_PRIME0x00000130UL, pqg.prime.data, | |||
276 | pqg.prime.len); | |||
277 | if (crv == CKR_OK0x00000000UL) | |||
278 | crv = sftk_forceAttribute(key, CKA_SUBPRIME0x00000131UL, pqg.subPrime.data, | |||
279 | pqg.subPrime.len); | |||
280 | if (crv == CKR_OK0x00000000UL) { | |||
281 | crv = jpake_MultipleSecItem2Attribute(key, copiedAndGeneratedAttrs, | |||
282 | NUM_ELEM(copiedAndGeneratedAttrs)(sizeof(copiedAndGeneratedAttrs) / sizeof(copiedAndGeneratedAttrs )[0])); | |||
283 | } | |||
284 | ||||
285 | if (crv == CKR_OK0x00000000UL) | |||
286 | crv = jpake_enforceKeyType(key, CKK_NSS_JPAKE_ROUND2((0x80000000UL | 0x4E534350) + 3)); | |||
287 | ||||
288 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
289 | return crv; | |||
290 | } | |||
291 | ||||
292 | CK_RV | |||
293 | jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams *param, | |||
294 | SFTKObject *sourceKey, SFTKObject *key) | |||
295 | { | |||
296 | PLArenaPool *arena; | |||
297 | SECItem K; | |||
298 | PQGParams pqg; | |||
299 | CK_RV crv; | |||
300 | SECItem peerID, signerID, x2s, x2, gx1, gx2, gx3, gx4; | |||
301 | SFTKItemTemplate sourceAttrs[] = { | |||
302 | { CKA_NSS_JPAKE_PEERID((0x80000000UL | 0x4E534350) + 27), &peerID }, | |||
303 | { CKA_NSS_JPAKE_SIGNERID((0x80000000UL | 0x4E534350) + 26), &signerID }, | |||
304 | { CKA_PRIME0x00000130UL, &pqg.prime }, | |||
305 | { CKA_SUBPRIME0x00000131UL, &pqg.subPrime }, | |||
306 | { CKA_NSS_JPAKE_X2((0x80000000UL | 0x4E534350) + 32), &x2 }, | |||
307 | { CKA_NSS_JPAKE_X2S((0x80000000UL | 0x4E534350) + 33), &x2s }, | |||
308 | { CKA_NSS_JPAKE_GX1((0x80000000UL | 0x4E534350) + 28), &gx1 }, | |||
309 | { CKA_NSS_JPAKE_GX2((0x80000000UL | 0x4E534350) + 29), &gx2 }, | |||
310 | { CKA_NSS_JPAKE_GX3((0x80000000UL | 0x4E534350) + 30), &gx3 }, | |||
311 | { CKA_NSS_JPAKE_GX4((0x80000000UL | 0x4E534350) + 31), &gx4 } | |||
312 | }; | |||
313 | ||||
314 | PORT_Assert(param != NULL)((param != ((void*)0))?((void)0):PR_Assert("param != NULL","jpakesftk.c" ,314)); | |||
315 | PORT_Assert(sourceKey != NULL)((sourceKey != ((void*)0))?((void)0):PR_Assert("sourceKey != NULL" ,"jpakesftk.c",315)); | |||
316 | PORT_Assert(key != NULL)((key != ((void*)0))?((void)0):PR_Assert("key != NULL","jpakesftk.c" ,316)); | |||
317 | ||||
318 | arena = PORT_NewArenaPORT_NewArena_Util(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE2048); | |||
319 | if (arena == NULL((void*)0)) | |||
320 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
321 | ||||
322 | /* TODO: verify key type CKK_NSS_JPAKE_ROUND2 */ | |||
323 | ||||
324 | crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs, | |||
325 | NUM_ELEM(sourceAttrs)(sizeof(sourceAttrs) / sizeof(sourceAttrs)[0])); | |||
326 | ||||
327 | /* Calculate base for B=base^x4s */ | |||
328 | if (crv == CKR_OK0x00000000UL) { | |||
329 | pqg.base.data = NULL((void*)0); | |||
330 | crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime, | |||
331 | &gx1, &gx2, &gx3, &pqg.base, | |||
332 | NULL((void*)0), NULL((void*)0), NULL((void*)0)), | |||
333 | CKR_MECHANISM_PARAM_INVALID0x00000071UL); | |||
334 | } | |||
335 | ||||
336 | /* Verify zero-knowledge proof for B */ | |||
337 | if (crv == CKR_OK0x00000000UL) | |||
338 | crv = jpake_Verify(arena, &pqg, hashType, &signerID, | |||
339 | peerID.data, peerID.len, ¶m->B); | |||
340 | if (crv == CKR_OK0x00000000UL) { | |||
341 | SECItem B; | |||
342 | B.data = param->B.pGX; | |||
343 | B.len = param->B.ulGXLen; | |||
344 | K.data = NULL((void*)0); | |||
345 | crv = jpake_mapStatus(JPAKE_Final(arena, &pqg.prime, &pqg.subPrime, | |||
346 | &x2, &gx4, &x2s, &B, &K), | |||
347 | CKR_MECHANISM_PARAM_INVALID0x00000071UL); | |||
348 | } | |||
349 | ||||
350 | /* Save key material into CKA_VALUE. */ | |||
351 | if (crv == CKR_OK0x00000000UL) | |||
352 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, K.data, K.len); | |||
353 | ||||
354 | if (crv == CKR_OK0x00000000UL) | |||
355 | crv = jpake_enforceKeyType(key, CKK_GENERIC_SECRET0x00000010UL); | |||
356 | ||||
357 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
358 | return crv; | |||
359 | } |