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
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
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
24 * Length of SEED in bytes specified in seedBytes.
26 * The underlying PKCS #11 module will check the values for L, N,
27 * and seedBytes. The rules for softoken are:
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:
37 * seedBbytes must be in the range [20..256].
39 * seedBbytes must be in the range [20..L/16].
42 PK11_PQG_ParamGenV2(unsigned int L
, unsigned int N
,
43 unsigned int seedBytes
, PQGParams
**pParams
, PQGVerify
**pVfy
)
45 PK11SlotInfo
*slot
= NULL
;
46 CK_ATTRIBUTE genTemplate
[5];
47 CK_ATTRIBUTE
*attrs
= genTemplate
;
48 int count
= sizeof(genTemplate
) / sizeof(genTemplate
[0]);
49 CK_MECHANISM mechanism
;
50 CK_OBJECT_HANDLE objectID
= CK_INVALID_HANDLE
;
52 CK_ATTRIBUTE pTemplate
[] = {
53 { CKA_PRIME
, NULL
, 0 },
54 { CKA_SUBPRIME
, NULL
, 0 },
55 { CKA_BASE
, NULL
, 0 },
57 CK_ATTRIBUTE vTemplate
[] = {
58 { CKA_NSS_PQG_COUNTER
, NULL
, 0 },
59 { CKA_NSS_PQG_SEED
, NULL
, 0 },
60 { CKA_NSS_PQG_H
, NULL
, 0 },
62 CK_ULONG primeBits
= L
;
63 CK_ULONG subPrimeBits
= N
;
64 int pTemplateCount
= sizeof(pTemplate
) / sizeof(pTemplate
[0]);
65 int vTemplateCount
= sizeof(vTemplate
) / sizeof(vTemplate
[0]);
66 PLArenaPool
*parena
= NULL
;
67 PLArenaPool
*varena
= NULL
;
68 PQGParams
*params
= NULL
;
69 PQGVerify
*verify
= NULL
;
70 CK_ULONG seedBits
= seedBytes
* 8;
75 if (primeBits
== (CK_ULONG
)-1) {
76 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
79 PK11_SETATTRS(attrs
, CKA_PRIME_BITS
, &primeBits
, sizeof(primeBits
));
81 if (subPrimeBits
!= 0) {
82 PK11_SETATTRS(attrs
, CKA_SUB_PRIME_BITS
,
83 &subPrimeBits
, sizeof(subPrimeBits
));
87 PK11_SETATTRS(attrs
, CKA_NSS_PQG_SEED_BITS
,
88 &seedBits
, sizeof(seedBits
));
91 count
= attrs
- genTemplate
;
92 PR_ASSERT(count
<= sizeof(genTemplate
) / sizeof(CK_ATTRIBUTE
));
94 slot
= PK11_GetInternalSlot();
97 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE
); /* shouldn't happen */
101 /* make sure the internal slot can handle DSA2 type parameters. */
102 if (primeBits
> 1024) {
103 CK_MECHANISM_INFO mechanism_info
;
105 if (!slot
->isThreadSafe
)
106 PK11_EnterSlotMonitor(slot
);
107 crv
= PK11_GETTAB(slot
)->C_GetMechanismInfo(slot
->slotID
,
108 CKM_DSA_PARAMETER_GEN
,
110 if (!slot
->isThreadSafe
)
111 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 if ((crv
!= CKR_OK
) || (mechanism_info
.ulMaxKeySize
< primeBits
)) {
117 slot
= PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN
, 0,
120 PORT_SetError(SEC_ERROR_NO_TOKEN
); /* can happen */
123 /* ditch seedBits in this case, they are NSS specific and at
124 * this point we have a token that claims to handle DSA2 */
131 /* Initialize the Key Gen Mechanism */
132 mechanism
.mechanism
= CKM_DSA_PARAMETER_GEN
;
133 mechanism
.pParameter
= NULL
;
134 mechanism
.ulParameterLen
= 0;
136 PK11_EnterSlotMonitor(slot
);
137 crv
= PK11_GETTAB(slot
)->C_GenerateKey(slot
->session
,
138 &mechanism
, genTemplate
, count
, &objectID
);
139 PK11_ExitSlotMonitor(slot
);
142 PORT_SetError(PK11_MapError(crv
));
146 parena
= PORT_NewArena(60);
151 crv
= PK11_GetAttributes(parena
, slot
, objectID
, pTemplate
, pTemplateCount
);
153 PORT_SetError(PK11_MapError(crv
));
157 params
= (PQGParams
*)PORT_ArenaAlloc(parena
, sizeof(PQGParams
));
158 if (params
== NULL
) {
163 params
->arena
= parena
;
164 params
->prime
.type
= siUnsignedInteger
;
165 params
->prime
.data
= pTemplate
[0].pValue
;
166 params
->prime
.len
= pTemplate
[0].ulValueLen
;
167 params
->subPrime
.type
= siUnsignedInteger
;
168 params
->subPrime
.data
= pTemplate
[1].pValue
;
169 params
->subPrime
.len
= pTemplate
[1].ulValueLen
;
170 params
->base
.type
= siUnsignedInteger
;
171 params
->base
.data
= pTemplate
[2].pValue
;
172 params
->base
.len
= pTemplate
[2].ulValueLen
;
174 varena
= PORT_NewArena(60);
179 crv
= PK11_GetAttributes(varena
, slot
, objectID
, vTemplate
, vTemplateCount
);
181 PORT_SetError(PK11_MapError(crv
));
185 verify
= (PQGVerify
*)PORT_ArenaAlloc(varena
, sizeof(PQGVerify
));
186 if (verify
== NULL
) {
190 verify
->arena
= varena
;
191 verify
->counter
= (unsigned int)(*(CK_ULONG
*)vTemplate
[0].pValue
);
192 verify
->seed
.type
= siUnsignedInteger
;
193 verify
->seed
.data
= vTemplate
[1].pValue
;
194 verify
->seed
.len
= vTemplate
[1].ulValueLen
;
195 verify
->h
.type
= siUnsignedInteger
;
196 verify
->h
.data
= vTemplate
[2].pValue
;
197 verify
->h
.len
= vTemplate
[2].ulValueLen
;
199 PK11_DestroyObject(slot
, objectID
);
208 if (objectID
!= CK_INVALID_HANDLE
) {
209 PK11_DestroyObject(slot
, objectID
);
211 if (parena
!= NULL
) {
212 PORT_FreeArena(parena
, PR_FALSE
);
214 if (varena
!= NULL
) {
215 PORT_FreeArena(varena
, PR_FALSE
);
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.
229 PK11_PQG_ParamGenSeedLen(unsigned int j
, unsigned int seedBytes
,
230 PQGParams
**pParams
, PQGVerify
**pVfy
)
232 unsigned int primeBits
= PQG_INDEX_TO_PBITS(j
);
233 return PK11_PQG_ParamGenV2(primeBits
, 0, seedBytes
, pParams
, pVfy
);
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.
241 PK11_PQG_ParamGen(unsigned int j
, PQGParams
**pParams
, PQGVerify
**pVfy
)
243 unsigned int primeBits
= PQG_INDEX_TO_PBITS(j
);
244 return PK11_PQG_ParamGenV2(primeBits
, 0, 0, pParams
, pVfy
);
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.
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.
259 PK11_PQG_VerifyParams(const PQGParams
*params
, const PQGVerify
*vfy
,
262 CK_ATTRIBUTE keyTempl
[] = {
263 { CKA_CLASS
, NULL
, 0 },
264 { CKA_KEY_TYPE
, NULL
, 0 },
265 { CKA_PRIME
, NULL
, 0 },
266 { CKA_SUBPRIME
, NULL
, 0 },
267 { CKA_BASE
, NULL
, 0 },
268 { CKA_TOKEN
, NULL
, 0 },
269 { CKA_NSS_PQG_COUNTER
, NULL
, 0 },
270 { CKA_NSS_PQG_SEED
, NULL
, 0 },
271 { CKA_NSS_PQG_H
, NULL
, 0 },
274 CK_BBOOL ckfalse
= CK_FALSE
;
275 CK_OBJECT_CLASS
class = CKO_DOMAIN_PARAMETERS
;
276 CK_KEY_TYPE keyType
= CKK_DSA
;
277 SECStatus rv
= SECSuccess
;
280 CK_OBJECT_HANDLE objectID
;
285 PK11_SETATTRS(attrs
, CKA_CLASS
, &class, sizeof(class));
287 PK11_SETATTRS(attrs
, CKA_KEY_TYPE
, &keyType
, sizeof(keyType
));
289 PK11_SETATTRS(attrs
, CKA_PRIME
, params
->prime
.data
,
292 PK11_SETATTRS(attrs
, CKA_SUBPRIME
, params
->subPrime
.data
,
293 params
->subPrime
.len
);
295 if (params
->base
.len
) {
296 PK11_SETATTRS(attrs
, CKA_BASE
, params
->base
.data
, params
->base
.len
);
299 PK11_SETATTRS(attrs
, CKA_TOKEN
, &ckfalse
, sizeof(ckfalse
));
302 if (vfy
->counter
!= -1) {
303 counter
= vfy
->counter
;
304 PK11_SETATTRS(attrs
, CKA_NSS_PQG_COUNTER
,
305 &counter
, sizeof(counter
));
308 PK11_SETATTRS(attrs
, CKA_NSS_PQG_SEED
,
309 vfy
->seed
.data
, vfy
->seed
.len
);
312 PK11_SETATTRS(attrs
, CKA_NSS_PQG_H
,
313 vfy
->h
.data
, vfy
->h
.len
);
318 keyCount
= attrs
- keyTempl
;
319 PORT_Assert(keyCount
<= sizeof(keyTempl
) / sizeof(keyTempl
[0]));
321 slot
= PK11_GetInternalSlot();
326 PK11_EnterSlotMonitor(slot
);
327 crv
= PK11_GETTAB(slot
)->C_CreateObject(slot
->session
, keyTempl
, keyCount
,
329 PK11_ExitSlotMonitor(slot
);
331 /* throw away the keys, we only wanted the return code */
332 PK11_DestroyObject(slot
, objectID
);
335 *result
= SECSuccess
;
336 if (crv
== CKR_ATTRIBUTE_VALUE_INVALID
) {
337 *result
= SECFailure
;
338 } else if (crv
!= CKR_OK
) {
339 PORT_SetError(PK11_MapError(crv
));
345 /**************************************************************************
346 * Free the PQGParams struct and the things it points to. *
347 **************************************************************************/
349 PK11_PQG_DestroyParams(PQGParams
*params
)
353 if (params
->arena
!= NULL
) {
354 PORT_FreeArena(params
->arena
, PR_FALSE
); /* don't zero it */
356 SECITEM_FreeItem(¶ms
->prime
, PR_FALSE
); /* don't free prime */
357 SECITEM_FreeItem(¶ms
->subPrime
, PR_FALSE
); /* don't free subPrime */
358 SECITEM_FreeItem(¶ms
->base
, PR_FALSE
); /* don't free base */
363 /**************************************************************************
364 * Free the PQGVerify struct and the things it points to. *
365 **************************************************************************/
367 PK11_PQG_DestroyVerify(PQGVerify
*vfy
)
371 if (vfy
->arena
!= NULL
) {
372 PORT_FreeArena(vfy
->arena
, PR_FALSE
); /* don't zero it */
374 SECITEM_FreeItem(&vfy
->seed
, PR_FALSE
); /* don't free seed */
375 SECITEM_FreeItem(&vfy
->h
, PR_FALSE
); /* don't free h */
380 #define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
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 **************************************************************************/
388 PK11_PQG_NewParams(const SECItem
*prime
, const SECItem
*subPrime
,
395 arena
= PORT_NewArena(PQG_DEFAULT_CHUNKSIZE
);
399 dest
= (PQGParams
*)PORT_ArenaZAlloc(arena
, sizeof(PQGParams
));
405 status
= SECITEM_CopyItem(arena
, &dest
->prime
, prime
);
406 if (status
!= SECSuccess
)
409 status
= SECITEM_CopyItem(arena
, &dest
->subPrime
, subPrime
);
410 if (status
!= SECSuccess
)
413 status
= SECITEM_CopyItem(arena
, &dest
->base
, base
);
414 if (status
!= SECSuccess
)
421 PORT_FreeArena(arena
, PR_FALSE
);
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 **************************************************************************/
430 PK11_PQG_GetPrimeFromParams(const PQGParams
*params
, SECItem
*prime
)
432 return SECITEM_CopyItem(NULL
, prime
, ¶ms
->prime
);
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 **************************************************************************/
440 PK11_PQG_GetSubPrimeFromParams(const PQGParams
*params
, SECItem
*subPrime
)
442 return SECITEM_CopyItem(NULL
, subPrime
, ¶ms
->subPrime
);
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 **************************************************************************/
450 PK11_PQG_GetBaseFromParams(const PQGParams
*params
, SECItem
*base
)
452 return SECITEM_CopyItem(NULL
, base
, ¶ms
->base
);
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 **************************************************************************/
461 PK11_PQG_NewVerify(unsigned int counter
, const SECItem
*seed
,
468 arena
= PORT_NewArena(PQG_DEFAULT_CHUNKSIZE
);
472 dest
= (PQGVerify
*)PORT_ArenaZAlloc(arena
, sizeof(PQGVerify
));
477 dest
->counter
= counter
;
479 status
= SECITEM_CopyItem(arena
, &dest
->seed
, seed
);
480 if (status
!= SECSuccess
)
483 status
= SECITEM_CopyItem(arena
, &dest
->h
, h
);
484 if (status
!= SECSuccess
)
491 PORT_FreeArena(arena
, PR_FALSE
);
495 /**************************************************************************
496 * Returns "counter" value from the PQGVerify.
497 **************************************************************************/
499 PK11_PQG_GetCounterFromVerify(const PQGVerify
*verify
)
501 return verify
->counter
;
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 **************************************************************************/
509 PK11_PQG_GetSeedFromVerify(const PQGVerify
*verify
, SECItem
*seed
)
511 return SECITEM_CopyItem(NULL
, seed
, &verify
->seed
);
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 **************************************************************************/
519 PK11_PQG_GetHFromVerify(const PQGVerify
*verify
, SECItem
*h
)
521 return SECITEM_CopyItem(NULL
, h
, &verify
->h
);