1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2001
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
36 /* Thse functions are stub functions which will get replaced with calls through
49 /* Generate PQGParams and PQGVerify structs.
50 * Length of P specified by j. Length of h will match length of P.
51 * Length of SEED in bytes specified in seedBytes.
52 * seedBbytes must be in the range [20..255] or an error will result.
55 PK11_PQG_ParamGenSeedLen( unsigned int j
, unsigned int seedBytes
,
56 PQGParams
**pParams
, PQGVerify
**pVfy
)
58 PK11SlotInfo
*slot
= NULL
;
59 CK_ATTRIBUTE genTemplate
[5];
60 CK_ATTRIBUTE
*attrs
= genTemplate
;
61 int count
= sizeof(genTemplate
)/sizeof(genTemplate
[0]);
62 CK_MECHANISM mechanism
;
63 CK_OBJECT_HANDLE objectID
= CK_INVALID_HANDLE
;
65 CK_ATTRIBUTE pTemplate
[] = {
66 { CKA_PRIME
, NULL
, 0 },
67 { CKA_SUBPRIME
, NULL
, 0 },
68 { CKA_BASE
, NULL
, 0 },
70 CK_ATTRIBUTE vTemplate
[] = {
71 { CKA_NETSCAPE_PQG_COUNTER
, NULL
, 0 },
72 { CKA_NETSCAPE_PQG_SEED
, NULL
, 0 },
73 { CKA_NETSCAPE_PQG_H
, NULL
, 0 },
75 int pTemplateCount
= sizeof(pTemplate
)/sizeof(pTemplate
[0]);
76 int vTemplateCount
= sizeof(vTemplate
)/sizeof(vTemplate
[0]);
77 PRArenaPool
*parena
= NULL
;
78 PRArenaPool
*varena
= NULL
;
79 PQGParams
*params
= NULL
;
80 PQGVerify
*verify
= NULL
;
81 CK_ULONG primeBits
= PQG_INDEX_TO_PBITS(j
);
82 CK_ULONG seedBits
= seedBytes
*8;
87 if (primeBits
== (CK_ULONG
)-1) {
88 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
91 PK11_SETATTRS(attrs
, CKA_PRIME_BITS
,&primeBits
,sizeof(primeBits
)); attrs
++;
93 PK11_SETATTRS(attrs
, CKA_NETSCAPE_PQG_SEED_BITS
,
94 &seedBits
, sizeof(seedBits
)); attrs
++;
96 count
= attrs
- genTemplate
;
97 PR_ASSERT(count
<= sizeof(genTemplate
)/sizeof(CK_ATTRIBUTE
));
99 slot
= PK11_GetInternalSlot();
105 /* Initialize the Key Gen Mechanism */
106 mechanism
.mechanism
= CKM_DSA_PARAMETER_GEN
;
107 mechanism
.pParameter
= NULL
;
108 mechanism
.ulParameterLen
= 0;
110 PK11_EnterSlotMonitor(slot
);
111 crv
= PK11_GETTAB(slot
)->C_GenerateKey(slot
->session
,
112 &mechanism
, genTemplate
, count
, &objectID
);
113 PK11_ExitSlotMonitor(slot
);
116 PORT_SetError( PK11_MapError(crv
) );
120 parena
= PORT_NewArena(60);
125 crv
= PK11_GetAttributes(parena
, slot
, objectID
, pTemplate
, pTemplateCount
);
127 PORT_SetError( PK11_MapError(crv
) );
132 params
= (PQGParams
*)PORT_ArenaAlloc(parena
,sizeof(PQGParams
));
133 if (params
== NULL
) {
138 params
->arena
= parena
;
139 params
->prime
.type
= siUnsignedInteger
;
140 params
->prime
.data
= pTemplate
[0].pValue
;
141 params
->prime
.len
= pTemplate
[0].ulValueLen
;
142 params
->subPrime
.type
= siUnsignedInteger
;
143 params
->subPrime
.data
= pTemplate
[1].pValue
;
144 params
->subPrime
.len
= pTemplate
[1].ulValueLen
;
145 params
->base
.type
= siUnsignedInteger
;
146 params
->base
.data
= pTemplate
[2].pValue
;
147 params
->base
.len
= pTemplate
[2].ulValueLen
;
150 varena
= PORT_NewArena(60);
155 crv
= PK11_GetAttributes(varena
, slot
, objectID
, vTemplate
, vTemplateCount
);
157 PORT_SetError( PK11_MapError(crv
) );
162 verify
= (PQGVerify
*)PORT_ArenaAlloc(varena
,sizeof(PQGVerify
));
163 if (verify
== NULL
) {
167 verify
->arena
= varena
;
168 verify
->counter
= (unsigned int)(*(CK_ULONG
*)vTemplate
[0].pValue
);
169 verify
->seed
.type
= siUnsignedInteger
;
170 verify
->seed
.data
= vTemplate
[1].pValue
;
171 verify
->seed
.len
= vTemplate
[1].ulValueLen
;
172 verify
->h
.type
= siUnsignedInteger
;
173 verify
->h
.data
= vTemplate
[2].pValue
;
174 verify
->h
.len
= vTemplate
[2].ulValueLen
;
176 PK11_DestroyObject(slot
,objectID
);
185 if (objectID
!= CK_INVALID_HANDLE
) {
186 PK11_DestroyObject(slot
,objectID
);
188 if (parena
!= NULL
) {
189 PORT_FreeArena(parena
,PR_FALSE
);
191 if (varena
!= NULL
) {
192 PORT_FreeArena(varena
,PR_FALSE
);
200 /* Generate PQGParams and PQGVerify structs.
201 * Length of seed and length of h both equal length of P.
202 * All lengths are specified by "j", according to the table above.
205 PK11_PQG_ParamGen(unsigned int j
, PQGParams
**pParams
, PQGVerify
**pVfy
)
207 return PK11_PQG_ParamGenSeedLen(j
, 0, pParams
, pVfy
);
210 /* Test PQGParams for validity as DSS PQG values.
211 * If vfy is non-NULL, test PQGParams to make sure they were generated
212 * using the specified seed, counter, and h values.
214 * Return value indicates whether Verification operation ran succesfully
215 * to completion, but does not indicate if PQGParams are valid or not.
216 * If return value is SECSuccess, then *pResult has these meanings:
217 * SECSuccess: PQGParams are valid.
218 * SECFailure: PQGParams are invalid.
222 PK11_PQG_VerifyParams(const PQGParams
*params
, const PQGVerify
*vfy
,
225 CK_ATTRIBUTE keyTempl
[] = {
226 { CKA_CLASS
, NULL
, 0 },
227 { CKA_KEY_TYPE
, NULL
, 0 },
228 { CKA_PRIME
, NULL
, 0 },
229 { CKA_SUBPRIME
, NULL
, 0 },
230 { CKA_BASE
, NULL
, 0 },
231 { CKA_TOKEN
, NULL
, 0 },
232 { CKA_NETSCAPE_PQG_COUNTER
, NULL
, 0 },
233 { CKA_NETSCAPE_PQG_SEED
, NULL
, 0 },
234 { CKA_NETSCAPE_PQG_H
, NULL
, 0 },
237 CK_BBOOL ckfalse
= CK_FALSE
;
238 CK_OBJECT_CLASS
class = CKO_KG_PARAMETERS
;
239 CK_KEY_TYPE keyType
= CKK_DSA
;
240 SECStatus rv
= SECSuccess
;
243 CK_OBJECT_HANDLE objectID
;
248 PK11_SETATTRS(attrs
, CKA_CLASS
, &class, sizeof(class)); attrs
++;
249 PK11_SETATTRS(attrs
, CKA_KEY_TYPE
, &keyType
, sizeof(keyType
)); attrs
++;
250 PK11_SETATTRS(attrs
, CKA_PRIME
, params
->prime
.data
,
251 params
->prime
.len
); attrs
++;
252 PK11_SETATTRS(attrs
, CKA_SUBPRIME
, params
->subPrime
.data
,
253 params
->subPrime
.len
); attrs
++;
254 PK11_SETATTRS(attrs
, CKA_BASE
,params
->base
.data
,params
->base
.len
); attrs
++;
255 PK11_SETATTRS(attrs
, CKA_TOKEN
, &ckfalse
, sizeof(ckfalse
)); attrs
++;
257 counter
= vfy
->counter
;
258 PK11_SETATTRS(attrs
, CKA_NETSCAPE_PQG_COUNTER
,
259 &counter
, sizeof(counter
)); attrs
++;
260 PK11_SETATTRS(attrs
, CKA_NETSCAPE_PQG_SEED
,
261 vfy
->seed
.data
, vfy
->seed
.len
); attrs
++;
262 PK11_SETATTRS(attrs
, CKA_NETSCAPE_PQG_H
,
263 vfy
->h
.data
, vfy
->h
.len
); attrs
++;
266 keyCount
= attrs
- keyTempl
;
267 PORT_Assert(keyCount
<= sizeof(keyTempl
)/sizeof(keyTempl
[0]));
270 slot
= PK11_GetInternalSlot();
275 PK11_EnterSlotMonitor(slot
);
276 crv
= PK11_GETTAB(slot
)->C_CreateObject(slot
->session
, keyTempl
, keyCount
,
278 PK11_ExitSlotMonitor(slot
);
280 /* throw away the keys, we only wanted the return code */
281 PK11_DestroyObject(slot
,objectID
);
284 *result
= SECSuccess
;
285 if (crv
== CKR_ATTRIBUTE_VALUE_INVALID
) {
286 *result
= SECFailure
;
287 } else if (crv
!= CKR_OK
) {
288 PORT_SetError( PK11_MapError(crv
) );
297 /**************************************************************************
298 * Free the PQGParams struct and the things it points to. *
299 **************************************************************************/
301 PK11_PQG_DestroyParams(PQGParams
*params
) {
304 if (params
->arena
!= NULL
) {
305 PORT_FreeArena(params
->arena
, PR_FALSE
); /* don't zero it */
307 SECITEM_FreeItem(¶ms
->prime
, PR_FALSE
); /* don't free prime */
308 SECITEM_FreeItem(¶ms
->subPrime
, PR_FALSE
); /* don't free subPrime */
309 SECITEM_FreeItem(¶ms
->base
, PR_FALSE
); /* don't free base */
314 /**************************************************************************
315 * Free the PQGVerify struct and the things it points to. *
316 **************************************************************************/
318 PK11_PQG_DestroyVerify(PQGVerify
*vfy
) {
321 if (vfy
->arena
!= NULL
) {
322 PORT_FreeArena(vfy
->arena
, PR_FALSE
); /* don't zero it */
324 SECITEM_FreeItem(&vfy
->seed
, PR_FALSE
); /* don't free seed */
325 SECITEM_FreeItem(&vfy
->h
, PR_FALSE
); /* don't free h */
330 #define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
332 /**************************************************************************
333 * Return a pointer to a new PQGParams struct that is constructed from *
334 * copies of the arguments passed in. *
335 * Return NULL on failure. *
336 **************************************************************************/
338 PK11_PQG_NewParams(const SECItem
* prime
, const SECItem
* subPrime
,
339 const SECItem
* base
) {
344 arena
= PORT_NewArena(PQG_DEFAULT_CHUNKSIZE
);
348 dest
= (PQGParams
*)PORT_ArenaZAlloc(arena
, sizeof(PQGParams
));
354 status
= SECITEM_CopyItem(arena
, &dest
->prime
, prime
);
355 if (status
!= SECSuccess
)
358 status
= SECITEM_CopyItem(arena
, &dest
->subPrime
, subPrime
);
359 if (status
!= SECSuccess
)
362 status
= SECITEM_CopyItem(arena
, &dest
->base
, base
);
363 if (status
!= SECSuccess
)
370 PORT_FreeArena(arena
, PR_FALSE
);
375 /**************************************************************************
376 * Fills in caller's "prime" SECItem with the prime value in params.
377 * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
378 **************************************************************************/
380 PK11_PQG_GetPrimeFromParams(const PQGParams
*params
, SECItem
* prime
) {
381 return SECITEM_CopyItem(NULL
, prime
, ¶ms
->prime
);
385 /**************************************************************************
386 * Fills in caller's "subPrime" SECItem with the prime value in params.
387 * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
388 **************************************************************************/
390 PK11_PQG_GetSubPrimeFromParams(const PQGParams
*params
, SECItem
* subPrime
) {
391 return SECITEM_CopyItem(NULL
, subPrime
, ¶ms
->subPrime
);
395 /**************************************************************************
396 * Fills in caller's "base" SECItem with the base value in params.
397 * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
398 **************************************************************************/
400 PK11_PQG_GetBaseFromParams(const PQGParams
*params
, SECItem
*base
) {
401 return SECITEM_CopyItem(NULL
, base
, ¶ms
->base
);
405 /**************************************************************************
406 * Return a pointer to a new PQGVerify struct that is constructed from *
407 * copies of the arguments passed in. *
408 * Return NULL on failure. *
409 **************************************************************************/
411 PK11_PQG_NewVerify(unsigned int counter
, const SECItem
* seed
,
417 arena
= PORT_NewArena(PQG_DEFAULT_CHUNKSIZE
);
421 dest
= (PQGVerify
*)PORT_ArenaZAlloc(arena
, sizeof(PQGVerify
));
426 dest
->counter
= counter
;
428 status
= SECITEM_CopyItem(arena
, &dest
->seed
, seed
);
429 if (status
!= SECSuccess
)
432 status
= SECITEM_CopyItem(arena
, &dest
->h
, h
);
433 if (status
!= SECSuccess
)
440 PORT_FreeArena(arena
, PR_FALSE
);
445 /**************************************************************************
446 * Returns "counter" value from the PQGVerify.
447 **************************************************************************/
449 PK11_PQG_GetCounterFromVerify(const PQGVerify
*verify
) {
450 return verify
->counter
;
453 /**************************************************************************
454 * Fills in caller's "seed" SECItem with the seed value in verify.
455 * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
456 **************************************************************************/
458 PK11_PQG_GetSeedFromVerify(const PQGVerify
*verify
, SECItem
*seed
) {
459 return SECITEM_CopyItem(NULL
, seed
, &verify
->seed
);
463 /**************************************************************************
464 * Fills in caller's "h" SECItem with the h value in verify.
465 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
466 **************************************************************************/
468 PK11_PQG_GetHFromVerify(const PQGVerify
*verify
, SECItem
* h
) {
469 return SECITEM_CopyItem(NULL
, h
, &verify
->h
);