/src/nss/lib/pk11wrap/pk11pqg.c
Line | Count | Source (jump to first uncovered line) |
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 | | /* Thse functions are stub functions which will get replaced with calls through |
5 | | * PKCS #11. |
6 | | */ |
7 | | |
8 | | #include "pk11func.h" |
9 | | #include "secmod.h" |
10 | | #include "secmodi.h" |
11 | | #include "secmodti.h" |
12 | | #include "pkcs11t.h" |
13 | | #include "pk11pqg.h" |
14 | | #include "secerr.h" |
15 | | |
16 | | /* Generate PQGParams and PQGVerify structs. |
17 | | * Length of P specified by L. |
18 | | * if L is greater than 1024 then the resulting verify parameters will be |
19 | | * DSA2. |
20 | | * Length of Q specified by N. If zero, The PKCS #11 module will |
21 | | * pick an appropriately sized Q for P. If N is specified and L = 1024, then |
22 | | * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters |
23 | | * will be returned. |
24 | | * Length of SEED in bytes specified in seedBytes. |
25 | | * |
26 | | * The underlying PKCS #11 module will check the values for L, N, |
27 | | * and seedBytes. The rules for softoken are: |
28 | | * |
29 | | * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits. |
30 | | * If L <= 1024, then N must be 0 or 160. |
31 | | * If L >= 1024, then L and N must match the following table: |
32 | | * L=1024 N=0 or 160 |
33 | | * L=2048 N=0 or 224 |
34 | | * L=2048 N=256 |
35 | | * L=3072 N=0 or 256 |
36 | | * if L <= 1024 |
37 | | * seedBbytes must be in the range [20..256]. |
38 | | * if L >= 1024 |
39 | | * seedBbytes must be in the range [20..L/16]. |
40 | | */ |
41 | | extern SECStatus |
42 | | PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, |
43 | | unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy) |
44 | 0 | { |
45 | 0 | PK11SlotInfo *slot = NULL; |
46 | 0 | CK_ATTRIBUTE genTemplate[5]; |
47 | 0 | CK_ATTRIBUTE *attrs = genTemplate; |
48 | 0 | int count = sizeof(genTemplate) / sizeof(genTemplate[0]); |
49 | 0 | CK_MECHANISM mechanism; |
50 | 0 | CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; |
51 | 0 | CK_RV crv; |
52 | 0 | CK_ATTRIBUTE pTemplate[] = { |
53 | 0 | { CKA_PRIME, NULL, 0 }, |
54 | 0 | { CKA_SUBPRIME, NULL, 0 }, |
55 | 0 | { CKA_BASE, NULL, 0 }, |
56 | 0 | }; |
57 | 0 | CK_ATTRIBUTE vTemplate[] = { |
58 | 0 | { CKA_NSS_PQG_COUNTER, NULL, 0 }, |
59 | 0 | { CKA_NSS_PQG_SEED, NULL, 0 }, |
60 | 0 | { CKA_NSS_PQG_H, NULL, 0 }, |
61 | 0 | }; |
62 | 0 | CK_ULONG primeBits = L; |
63 | 0 | CK_ULONG subPrimeBits = N; |
64 | 0 | int pTemplateCount = sizeof(pTemplate) / sizeof(pTemplate[0]); |
65 | 0 | int vTemplateCount = sizeof(vTemplate) / sizeof(vTemplate[0]); |
66 | 0 | PLArenaPool *parena = NULL; |
67 | 0 | PLArenaPool *varena = NULL; |
68 | 0 | PQGParams *params = NULL; |
69 | 0 | PQGVerify *verify = NULL; |
70 | 0 | CK_ULONG seedBits = seedBytes * 8; |
71 | |
|
72 | 0 | *pParams = NULL; |
73 | 0 | *pVfy = NULL; |
74 | |
|
75 | 0 | if (primeBits == (CK_ULONG)-1) { |
76 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
77 | 0 | goto loser; |
78 | 0 | } |
79 | 0 | PK11_SETATTRS(attrs, CKA_PRIME_BITS, &primeBits, sizeof(primeBits)); |
80 | 0 | attrs++; |
81 | 0 | if (subPrimeBits != 0) { |
82 | 0 | PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS, |
83 | 0 | &subPrimeBits, sizeof(subPrimeBits)); |
84 | 0 | attrs++; |
85 | 0 | } |
86 | 0 | if (seedBits != 0) { |
87 | 0 | PK11_SETATTRS(attrs, CKA_NSS_PQG_SEED_BITS, |
88 | 0 | &seedBits, sizeof(seedBits)); |
89 | 0 | attrs++; |
90 | 0 | } |
91 | 0 | count = attrs - genTemplate; |
92 | 0 | PR_ASSERT(count <= sizeof(genTemplate) / sizeof(CK_ATTRIBUTE)); |
93 | |
|
94 | 0 | slot = PK11_GetInternalSlot(); |
95 | 0 | if (slot == NULL) { |
96 | | /* set error */ |
97 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); /* shouldn't happen */ |
98 | 0 | goto loser; |
99 | 0 | } |
100 | | |
101 | | /* make sure the internal slot can handle DSA2 type parameters. */ |
102 | 0 | if (primeBits > 1024) { |
103 | 0 | CK_MECHANISM_INFO mechanism_info; |
104 | |
|
105 | 0 | if (!slot->isThreadSafe) |
106 | 0 | PK11_EnterSlotMonitor(slot); |
107 | 0 | crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, |
108 | 0 | CKM_DSA_PARAMETER_GEN, |
109 | 0 | &mechanism_info); |
110 | 0 | if (!slot->isThreadSafe) |
111 | 0 | PK11_ExitSlotMonitor(slot); |
112 | | /* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the |
113 | | * mechanism List. If we get a failure asking for this value, we know |
114 | | * it can't handle DSA2 */ |
115 | 0 | if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) { |
116 | 0 | PK11_FreeSlot(slot); |
117 | 0 | slot = PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN, 0, |
118 | 0 | primeBits, NULL); |
119 | 0 | if (slot == NULL) { |
120 | 0 | PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */ |
121 | 0 | goto loser; |
122 | 0 | } |
123 | | /* ditch seedBits in this case, they are NSS specific and at |
124 | | * this point we have a token that claims to handle DSA2 */ |
125 | 0 | if (seedBits) { |
126 | 0 | attrs--; |
127 | 0 | } |
128 | 0 | } |
129 | 0 | } |
130 | | |
131 | | /* Initialize the Key Gen Mechanism */ |
132 | 0 | mechanism.mechanism = CKM_DSA_PARAMETER_GEN; |
133 | 0 | mechanism.pParameter = NULL; |
134 | 0 | mechanism.ulParameterLen = 0; |
135 | |
|
136 | 0 | PK11_EnterSlotMonitor(slot); |
137 | 0 | crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, |
138 | 0 | &mechanism, genTemplate, count, &objectID); |
139 | 0 | PK11_ExitSlotMonitor(slot); |
140 | |
|
141 | 0 | if (crv != CKR_OK) { |
142 | 0 | PORT_SetError(PK11_MapError(crv)); |
143 | 0 | goto loser; |
144 | 0 | } |
145 | | |
146 | 0 | parena = PORT_NewArena(60); |
147 | 0 | if (!parena) { |
148 | 0 | goto loser; |
149 | 0 | } |
150 | | |
151 | 0 | crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); |
152 | 0 | if (crv != CKR_OK) { |
153 | 0 | PORT_SetError(PK11_MapError(crv)); |
154 | 0 | goto loser; |
155 | 0 | } |
156 | | |
157 | 0 | params = (PQGParams *)PORT_ArenaAlloc(parena, sizeof(PQGParams)); |
158 | 0 | if (params == NULL) { |
159 | 0 | goto loser; |
160 | 0 | } |
161 | | |
162 | | /* fill in Params */ |
163 | 0 | params->arena = parena; |
164 | 0 | params->prime.type = siUnsignedInteger; |
165 | 0 | params->prime.data = pTemplate[0].pValue; |
166 | 0 | params->prime.len = pTemplate[0].ulValueLen; |
167 | 0 | params->subPrime.type = siUnsignedInteger; |
168 | 0 | params->subPrime.data = pTemplate[1].pValue; |
169 | 0 | params->subPrime.len = pTemplate[1].ulValueLen; |
170 | 0 | params->base.type = siUnsignedInteger; |
171 | 0 | params->base.data = pTemplate[2].pValue; |
172 | 0 | params->base.len = pTemplate[2].ulValueLen; |
173 | |
|
174 | 0 | varena = PORT_NewArena(60); |
175 | 0 | if (!varena) { |
176 | 0 | goto loser; |
177 | 0 | } |
178 | | |
179 | 0 | crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); |
180 | 0 | if (crv != CKR_OK) { |
181 | 0 | PORT_SetError(PK11_MapError(crv)); |
182 | 0 | goto loser; |
183 | 0 | } |
184 | | |
185 | 0 | verify = (PQGVerify *)PORT_ArenaAlloc(varena, sizeof(PQGVerify)); |
186 | 0 | if (verify == NULL) { |
187 | 0 | goto loser; |
188 | 0 | } |
189 | | /* fill in Params */ |
190 | 0 | verify->arena = varena; |
191 | 0 | verify->counter = (unsigned int)(*(CK_ULONG *)vTemplate[0].pValue); |
192 | 0 | verify->seed.type = siUnsignedInteger; |
193 | 0 | verify->seed.data = vTemplate[1].pValue; |
194 | 0 | verify->seed.len = vTemplate[1].ulValueLen; |
195 | 0 | verify->h.type = siUnsignedInteger; |
196 | 0 | verify->h.data = vTemplate[2].pValue; |
197 | 0 | verify->h.len = vTemplate[2].ulValueLen; |
198 | |
|
199 | 0 | PK11_DestroyObject(slot, objectID); |
200 | 0 | PK11_FreeSlot(slot); |
201 | |
|
202 | 0 | *pParams = params; |
203 | 0 | *pVfy = verify; |
204 | |
|
205 | 0 | return SECSuccess; |
206 | | |
207 | 0 | loser: |
208 | 0 | if (objectID != CK_INVALID_HANDLE) { |
209 | 0 | PK11_DestroyObject(slot, objectID); |
210 | 0 | } |
211 | 0 | if (parena != NULL) { |
212 | 0 | PORT_FreeArena(parena, PR_FALSE); |
213 | 0 | } |
214 | 0 | if (varena != NULL) { |
215 | 0 | PORT_FreeArena(varena, PR_FALSE); |
216 | 0 | } |
217 | 0 | if (slot) { |
218 | 0 | PK11_FreeSlot(slot); |
219 | 0 | } |
220 | 0 | return SECFailure; |
221 | 0 | } |
222 | | |
223 | | /* Generate PQGParams and PQGVerify structs. |
224 | | * Length of P specified by j. Length of h will match length of P. |
225 | | * Length of SEED in bytes specified in seedBytes. |
226 | | * seedBbytes must be in the range [20..255] or an error will result. |
227 | | */ |
228 | | extern SECStatus |
229 | | PK11_PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes, |
230 | | PQGParams **pParams, PQGVerify **pVfy) |
231 | 0 | { |
232 | 0 | unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
233 | 0 | return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy); |
234 | 0 | } |
235 | | |
236 | | /* Generate PQGParams and PQGVerify structs. |
237 | | * Length of seed and length of h both equal length of P. |
238 | | * All lengths are specified by "j", according to the table above. |
239 | | */ |
240 | | extern SECStatus |
241 | | PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) |
242 | 0 | { |
243 | 0 | unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
244 | 0 | return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy); |
245 | 0 | } |
246 | | |
247 | | /* Test PQGParams for validity as DSS PQG values. |
248 | | * If vfy is non-NULL, test PQGParams to make sure they were generated |
249 | | * using the specified seed, counter, and h values. |
250 | | * |
251 | | * Return value indicates whether Verification operation ran successfully |
252 | | * to completion, but does not indicate if PQGParams are valid or not. |
253 | | * If return value is SECSuccess, then *pResult has these meanings: |
254 | | * SECSuccess: PQGParams are valid. |
255 | | * SECFailure: PQGParams are invalid. |
256 | | */ |
257 | | |
258 | | extern SECStatus |
259 | | PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy, |
260 | | SECStatus *result) |
261 | 0 | { |
262 | 0 | CK_ATTRIBUTE keyTempl[] = { |
263 | 0 | { CKA_CLASS, NULL, 0 }, |
264 | 0 | { CKA_KEY_TYPE, NULL, 0 }, |
265 | 0 | { CKA_PRIME, NULL, 0 }, |
266 | 0 | { CKA_SUBPRIME, NULL, 0 }, |
267 | 0 | { CKA_BASE, NULL, 0 }, |
268 | 0 | { CKA_TOKEN, NULL, 0 }, |
269 | 0 | { CKA_NSS_PQG_COUNTER, NULL, 0 }, |
270 | 0 | { CKA_NSS_PQG_SEED, NULL, 0 }, |
271 | 0 | { CKA_NSS_PQG_H, NULL, 0 }, |
272 | 0 | }; |
273 | 0 | CK_ATTRIBUTE *attrs; |
274 | 0 | CK_BBOOL ckfalse = CK_FALSE; |
275 | 0 | CK_OBJECT_CLASS class = CKO_DOMAIN_PARAMETERS; |
276 | 0 | CK_KEY_TYPE keyType = CKK_DSA; |
277 | 0 | SECStatus rv = SECSuccess; |
278 | 0 | PK11SlotInfo *slot; |
279 | 0 | int keyCount; |
280 | 0 | CK_OBJECT_HANDLE objectID; |
281 | 0 | CK_ULONG counter; |
282 | 0 | CK_RV crv; |
283 | |
|
284 | 0 | attrs = keyTempl; |
285 | 0 | PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); |
286 | 0 | attrs++; |
287 | 0 | PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
288 | 0 | attrs++; |
289 | 0 | PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, |
290 | 0 | params->prime.len); |
291 | 0 | attrs++; |
292 | 0 | PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, |
293 | 0 | params->subPrime.len); |
294 | 0 | attrs++; |
295 | 0 | if (params->base.len) { |
296 | 0 | PK11_SETATTRS(attrs, CKA_BASE, params->base.data, params->base.len); |
297 | 0 | attrs++; |
298 | 0 | } |
299 | 0 | PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); |
300 | 0 | attrs++; |
301 | 0 | if (vfy) { |
302 | 0 | if (vfy->counter != -1) { |
303 | 0 | counter = vfy->counter; |
304 | 0 | PK11_SETATTRS(attrs, CKA_NSS_PQG_COUNTER, |
305 | 0 | &counter, sizeof(counter)); |
306 | 0 | attrs++; |
307 | 0 | } |
308 | 0 | PK11_SETATTRS(attrs, CKA_NSS_PQG_SEED, |
309 | 0 | vfy->seed.data, vfy->seed.len); |
310 | 0 | attrs++; |
311 | 0 | if (vfy->h.len) { |
312 | 0 | PK11_SETATTRS(attrs, CKA_NSS_PQG_H, |
313 | 0 | vfy->h.data, vfy->h.len); |
314 | 0 | attrs++; |
315 | 0 | } |
316 | 0 | } |
317 | |
|
318 | 0 | keyCount = attrs - keyTempl; |
319 | 0 | PORT_Assert(keyCount <= sizeof(keyTempl) / sizeof(keyTempl[0])); |
320 | |
|
321 | 0 | slot = PK11_GetInternalSlot(); |
322 | 0 | if (slot == NULL) { |
323 | 0 | return SECFailure; |
324 | 0 | } |
325 | | |
326 | 0 | PK11_EnterSlotMonitor(slot); |
327 | 0 | crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount, |
328 | 0 | &objectID); |
329 | 0 | PK11_ExitSlotMonitor(slot); |
330 | | |
331 | | /* throw away the keys, we only wanted the return code */ |
332 | 0 | PK11_DestroyObject(slot, objectID); |
333 | 0 | PK11_FreeSlot(slot); |
334 | |
|
335 | 0 | *result = SECSuccess; |
336 | 0 | if (crv == CKR_ATTRIBUTE_VALUE_INVALID) { |
337 | 0 | *result = SECFailure; |
338 | 0 | } else if (crv != CKR_OK) { |
339 | 0 | PORT_SetError(PK11_MapError(crv)); |
340 | 0 | rv = SECFailure; |
341 | 0 | } |
342 | 0 | return rv; |
343 | 0 | } |
344 | | |
345 | | /************************************************************************** |
346 | | * Free the PQGParams struct and the things it points to. * |
347 | | **************************************************************************/ |
348 | | extern void |
349 | | PK11_PQG_DestroyParams(PQGParams *params) |
350 | 0 | { |
351 | 0 | if (params == NULL) |
352 | 0 | return; |
353 | 0 | if (params->arena != NULL) { |
354 | 0 | PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */ |
355 | 0 | } else { |
356 | 0 | SECITEM_FreeItem(¶ms->prime, PR_FALSE); /* don't free prime */ |
357 | 0 | SECITEM_FreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */ |
358 | 0 | SECITEM_FreeItem(¶ms->base, PR_FALSE); /* don't free base */ |
359 | 0 | PORT_Free(params); |
360 | 0 | } |
361 | 0 | } |
362 | | |
363 | | /************************************************************************** |
364 | | * Free the PQGVerify struct and the things it points to. * |
365 | | **************************************************************************/ |
366 | | extern void |
367 | | PK11_PQG_DestroyVerify(PQGVerify *vfy) |
368 | 0 | { |
369 | 0 | if (vfy == NULL) |
370 | 0 | return; |
371 | 0 | if (vfy->arena != NULL) { |
372 | 0 | PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */ |
373 | 0 | } else { |
374 | 0 | SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */ |
375 | 0 | SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */ |
376 | 0 | PORT_Free(vfy); |
377 | 0 | } |
378 | 0 | } |
379 | | |
380 | 0 | #define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */ |
381 | | |
382 | | /************************************************************************** |
383 | | * Return a pointer to a new PQGParams struct that is constructed from * |
384 | | * copies of the arguments passed in. * |
385 | | * Return NULL on failure. * |
386 | | **************************************************************************/ |
387 | | extern PQGParams * |
388 | | PK11_PQG_NewParams(const SECItem *prime, const SECItem *subPrime, |
389 | | const SECItem *base) |
390 | 0 | { |
391 | 0 | PLArenaPool *arena; |
392 | 0 | PQGParams *dest; |
393 | 0 | SECStatus status; |
394 | |
|
395 | 0 | arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE); |
396 | 0 | if (arena == NULL) |
397 | 0 | goto loser; |
398 | | |
399 | 0 | dest = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams)); |
400 | 0 | if (dest == NULL) |
401 | 0 | goto loser; |
402 | | |
403 | 0 | dest->arena = arena; |
404 | |
|
405 | 0 | status = SECITEM_CopyItem(arena, &dest->prime, prime); |
406 | 0 | if (status != SECSuccess) |
407 | 0 | goto loser; |
408 | | |
409 | 0 | status = SECITEM_CopyItem(arena, &dest->subPrime, subPrime); |
410 | 0 | if (status != SECSuccess) |
411 | 0 | goto loser; |
412 | | |
413 | 0 | status = SECITEM_CopyItem(arena, &dest->base, base); |
414 | 0 | if (status != SECSuccess) |
415 | 0 | goto loser; |
416 | | |
417 | 0 | return dest; |
418 | | |
419 | 0 | loser: |
420 | 0 | if (arena != NULL) |
421 | 0 | PORT_FreeArena(arena, PR_FALSE); |
422 | 0 | return NULL; |
423 | 0 | } |
424 | | |
425 | | /************************************************************************** |
426 | | * Fills in caller's "prime" SECItem with the prime value in params. |
427 | | * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE); |
428 | | **************************************************************************/ |
429 | | extern SECStatus |
430 | | PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem *prime) |
431 | 0 | { |
432 | 0 | return SECITEM_CopyItem(NULL, prime, ¶ms->prime); |
433 | 0 | } |
434 | | |
435 | | /************************************************************************** |
436 | | * Fills in caller's "subPrime" SECItem with the prime value in params. |
437 | | * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE); |
438 | | **************************************************************************/ |
439 | | extern SECStatus |
440 | | PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem *subPrime) |
441 | 0 | { |
442 | 0 | return SECITEM_CopyItem(NULL, subPrime, ¶ms->subPrime); |
443 | 0 | } |
444 | | |
445 | | /************************************************************************** |
446 | | * Fills in caller's "base" SECItem with the base value in params. |
447 | | * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE); |
448 | | **************************************************************************/ |
449 | | extern SECStatus |
450 | | PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) |
451 | 0 | { |
452 | 0 | return SECITEM_CopyItem(NULL, base, ¶ms->base); |
453 | 0 | } |
454 | | |
455 | | /************************************************************************** |
456 | | * Return a pointer to a new PQGVerify struct that is constructed from * |
457 | | * copies of the arguments passed in. * |
458 | | * Return NULL on failure. * |
459 | | **************************************************************************/ |
460 | | extern PQGVerify * |
461 | | PK11_PQG_NewVerify(unsigned int counter, const SECItem *seed, |
462 | | const SECItem *h) |
463 | 0 | { |
464 | 0 | PLArenaPool *arena; |
465 | 0 | PQGVerify *dest; |
466 | 0 | SECStatus status; |
467 | |
|
468 | 0 | arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE); |
469 | 0 | if (arena == NULL) |
470 | 0 | goto loser; |
471 | | |
472 | 0 | dest = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify)); |
473 | 0 | if (dest == NULL) |
474 | 0 | goto loser; |
475 | | |
476 | 0 | dest->arena = arena; |
477 | 0 | dest->counter = counter; |
478 | |
|
479 | 0 | status = SECITEM_CopyItem(arena, &dest->seed, seed); |
480 | 0 | if (status != SECSuccess) |
481 | 0 | goto loser; |
482 | | |
483 | 0 | status = SECITEM_CopyItem(arena, &dest->h, h); |
484 | 0 | if (status != SECSuccess) |
485 | 0 | goto loser; |
486 | | |
487 | 0 | return dest; |
488 | | |
489 | 0 | loser: |
490 | 0 | if (arena != NULL) |
491 | 0 | PORT_FreeArena(arena, PR_FALSE); |
492 | 0 | return NULL; |
493 | 0 | } |
494 | | |
495 | | /************************************************************************** |
496 | | * Returns "counter" value from the PQGVerify. |
497 | | **************************************************************************/ |
498 | | extern unsigned int |
499 | | PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) |
500 | 0 | { |
501 | 0 | return verify->counter; |
502 | 0 | } |
503 | | |
504 | | /************************************************************************** |
505 | | * Fills in caller's "seed" SECItem with the seed value in verify. |
506 | | * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE); |
507 | | **************************************************************************/ |
508 | | extern SECStatus |
509 | | PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) |
510 | 0 | { |
511 | 0 | return SECITEM_CopyItem(NULL, seed, &verify->seed); |
512 | 0 | } |
513 | | |
514 | | /************************************************************************** |
515 | | * Fills in caller's "h" SECItem with the h value in verify. |
516 | | * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); |
517 | | **************************************************************************/ |
518 | | extern SECStatus |
519 | | PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem *h) |
520 | 0 | { |
521 | 0 | return SECITEM_CopyItem(NULL, h, &verify->h); |
522 | 0 | } |