OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 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 | 4 /* Thse functions are stub functions which will get replaced with calls through |
5 * PKCS #11. | 5 * PKCS #11. |
6 */ | 6 */ |
7 | 7 |
8 #include "pk11func.h" | 8 #include "pk11func.h" |
9 #include "secmod.h" | 9 #include "secmod.h" |
10 #include "secmodi.h" | 10 #include "secmodi.h" |
11 #include "secmodti.h" | 11 #include "secmodti.h" |
12 #include "pkcs11t.h" | 12 #include "pkcs11t.h" |
13 #include "pk11pqg.h" | 13 #include "pk11pqg.h" |
14 #include "secerr.h" | 14 #include "secerr.h" |
15 | 15 |
16 | 16 |
17 /* Generate PQGParams and PQGVerify structs. | 17 /* Generate PQGParams and PQGVerify structs. |
18 * Length of P specified by j. Length of h will match length of P. | 18 * Length of P specified by L. |
| 19 * if L is greater than 1024 then the resulting verify parameters will be |
| 20 * DSA2. |
| 21 * Length of Q specified by N. If zero, The PKCS #11 module will |
| 22 * pick an appropriately sized Q for P. If N is specified and L = 1024, then |
| 23 * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters |
| 24 * will be returned. |
19 * Length of SEED in bytes specified in seedBytes. | 25 * Length of SEED in bytes specified in seedBytes. |
20 * seedBbytes must be in the range [20..255] or an error will result. | 26 * |
| 27 * The underlying PKCS #11 module will check the values for L, N, |
| 28 * and seedBytes. The rules for softoken are: |
| 29 * |
| 30 * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits. |
| 31 * If L <= 1024, then N must be 0 or 160. |
| 32 * If L >= 1024, then L and N must match the following table: |
| 33 * L=1024 N=0 or 160 |
| 34 * L=2048 N=0 or 224 |
| 35 * L=2048 N=256 |
| 36 * L=3072 N=0 or 256 |
| 37 * if L <= 1024 |
| 38 * seedBbytes must be in the range [20..256]. |
| 39 * if L >= 1024 |
| 40 * seedBbytes must be in the range [20..L/16]. |
21 */ | 41 */ |
22 extern SECStatus | 42 extern SECStatus |
23 PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, | 43 PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, |
24 » » » » PQGParams **pParams, PQGVerify **pVfy) | 44 » unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy) |
25 { | 45 { |
26 PK11SlotInfo *slot = NULL; | 46 PK11SlotInfo *slot = NULL; |
27 CK_ATTRIBUTE genTemplate[5]; | 47 CK_ATTRIBUTE genTemplate[5]; |
28 CK_ATTRIBUTE *attrs = genTemplate; | 48 CK_ATTRIBUTE *attrs = genTemplate; |
29 int count = sizeof(genTemplate)/sizeof(genTemplate[0]); | 49 int count = sizeof(genTemplate)/sizeof(genTemplate[0]); |
30 CK_MECHANISM mechanism; | 50 CK_MECHANISM mechanism; |
31 CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; | 51 CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; |
32 CK_RV crv; | 52 CK_RV crv; |
33 CK_ATTRIBUTE pTemplate[] = { | 53 CK_ATTRIBUTE pTemplate[] = { |
34 { CKA_PRIME, NULL, 0 }, | 54 { CKA_PRIME, NULL, 0 }, |
35 { CKA_SUBPRIME, NULL, 0 }, | 55 { CKA_SUBPRIME, NULL, 0 }, |
36 { CKA_BASE, NULL, 0 }, | 56 { CKA_BASE, NULL, 0 }, |
37 }; | 57 }; |
38 CK_ATTRIBUTE vTemplate[] = { | 58 CK_ATTRIBUTE vTemplate[] = { |
39 { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, | 59 { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, |
40 { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, | 60 { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, |
41 { CKA_NETSCAPE_PQG_H, NULL, 0 }, | 61 { CKA_NETSCAPE_PQG_H, NULL, 0 }, |
42 }; | 62 }; |
| 63 CK_ULONG primeBits = L; |
| 64 CK_ULONG subPrimeBits = N; |
43 int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]); | 65 int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]); |
44 int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]); | 66 int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]); |
45 PRArenaPool *parena = NULL; | 67 PRArenaPool *parena = NULL; |
46 PRArenaPool *varena = NULL; | 68 PRArenaPool *varena = NULL; |
47 PQGParams *params = NULL; | 69 PQGParams *params = NULL; |
48 PQGVerify *verify = NULL; | 70 PQGVerify *verify = NULL; |
49 CK_ULONG primeBits = PQG_INDEX_TO_PBITS(j); | |
50 CK_ULONG seedBits = seedBytes*8; | 71 CK_ULONG seedBits = seedBytes*8; |
51 | 72 |
52 *pParams = NULL; | 73 *pParams = NULL; |
53 *pVfy = NULL; | 74 *pVfy = NULL; |
54 | 75 |
55 if (primeBits == (CK_ULONG)-1) { | 76 if (primeBits == (CK_ULONG)-1) { |
56 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 77 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
57 goto loser; | 78 goto loser; |
58 } | 79 } |
59 PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++; | 80 PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++; |
| 81 if (subPrimeBits != 0) { |
| 82 PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS, |
| 83 &subPrimeBits, sizeof(subPrimeBits)); attrs++; |
| 84 } |
60 if (seedBits != 0) { | 85 if (seedBits != 0) { |
61 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, | 86 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, |
62 &seedBits, sizeof(seedBits)); attrs++; | 87 &seedBits, sizeof(seedBits)); attrs++; |
63 } | 88 } |
64 count = attrs - genTemplate; | 89 count = attrs - genTemplate; |
65 PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); | 90 PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); |
66 | 91 |
67 slot = PK11_GetInternalSlot(); | 92 slot = PK11_GetInternalSlot(); |
68 if (slot == NULL) { | 93 if (slot == NULL) { |
69 /* set error */ | 94 /* set error */ |
| 95 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);/* shouldn't happen */ |
70 goto loser; | 96 goto loser; |
71 } | 97 } |
72 | 98 |
| 99 /* make sure the internal slot can handle DSA2 type parameters. */ |
| 100 if (primeBits > 1024) { |
| 101 CK_MECHANISM_INFO mechanism_info; |
| 102 |
| 103 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); |
| 104 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, |
| 105 CKM_DSA_PARAMETER_GEN, &mechanism_info); |
| 106 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); |
| 107 /* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the |
| 108 * mechanism List. If we get a failure asking for this value, we know |
| 109 * it can't handle DSA2 */ |
| 110 if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) { |
| 111 PK11_FreeSlot(slot); |
| 112 slot = PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN, 0, |
| 113 primeBits, NULL); |
| 114 if (slot == NULL) { |
| 115 PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */ |
| 116 goto loser; |
| 117 } |
| 118 /* ditch seedBits in this case, they are NSS specific and at |
| 119 * this point we have a token that claims to handle DSA2 */ |
| 120 if (seedBits) { |
| 121 attrs--; |
| 122 } |
| 123 } |
| 124 } |
| 125 |
73 /* Initialize the Key Gen Mechanism */ | 126 /* Initialize the Key Gen Mechanism */ |
74 mechanism.mechanism = CKM_DSA_PARAMETER_GEN; | 127 mechanism.mechanism = CKM_DSA_PARAMETER_GEN; |
75 mechanism.pParameter = NULL; | 128 mechanism.pParameter = NULL; |
76 mechanism.ulParameterLen = 0; | 129 mechanism.ulParameterLen = 0; |
77 | 130 |
78 PK11_EnterSlotMonitor(slot); | 131 PK11_EnterSlotMonitor(slot); |
79 crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, | 132 crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, |
80 &mechanism, genTemplate, count, &objectID); | 133 &mechanism, genTemplate, count, &objectID); |
81 PK11_ExitSlotMonitor(slot); | 134 PK11_ExitSlotMonitor(slot); |
82 | 135 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (varena != NULL) { | 212 if (varena != NULL) { |
160 PORT_FreeArena(varena,PR_FALSE); | 213 PORT_FreeArena(varena,PR_FALSE); |
161 } | 214 } |
162 if (slot) { | 215 if (slot) { |
163 PK11_FreeSlot(slot); | 216 PK11_FreeSlot(slot); |
164 } | 217 } |
165 return SECFailure; | 218 return SECFailure; |
166 } | 219 } |
167 | 220 |
168 /* Generate PQGParams and PQGVerify structs. | 221 /* Generate PQGParams and PQGVerify structs. |
| 222 * Length of P specified by j. Length of h will match length of P. |
| 223 * Length of SEED in bytes specified in seedBytes. |
| 224 * seedBbytes must be in the range [20..255] or an error will result. |
| 225 */ |
| 226 extern SECStatus |
| 227 PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, |
| 228 PQGParams **pParams, PQGVerify **pVfy) |
| 229 { |
| 230 unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
| 231 return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy); |
| 232 } |
| 233 |
| 234 /* Generate PQGParams and PQGVerify structs. |
169 * Length of seed and length of h both equal length of P. | 235 * Length of seed and length of h both equal length of P. |
170 * All lengths are specified by "j", according to the table above. | 236 * All lengths are specified by "j", according to the table above. |
171 */ | 237 */ |
172 extern SECStatus | 238 extern SECStatus |
173 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) | 239 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) |
174 { | 240 { |
175 return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy); | 241 unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
| 242 return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy); |
176 } | 243 } |
177 | 244 |
178 /* Test PQGParams for validity as DSS PQG values. | 245 /* Test PQGParams for validity as DSS PQG values. |
179 * If vfy is non-NULL, test PQGParams to make sure they were generated | 246 * If vfy is non-NULL, test PQGParams to make sure they were generated |
180 * using the specified seed, counter, and h values. | 247 * using the specified seed, counter, and h values. |
181 * | 248 * |
182 * Return value indicates whether Verification operation ran successfully | 249 * Return value indicates whether Verification operation ran successfully |
183 * to completion, but does not indicate if PQGParams are valid or not. | 250 * to completion, but does not indicate if PQGParams are valid or not. |
184 * If return value is SECSuccess, then *pResult has these meanings: | 251 * If return value is SECSuccess, then *pResult has these meanings: |
185 * SECSuccess: PQGParams are valid. | 252 * SECSuccess: PQGParams are valid. |
(...skipping 26 matching lines...) Expand all Loading... |
212 CK_ULONG counter; | 279 CK_ULONG counter; |
213 CK_RV crv; | 280 CK_RV crv; |
214 | 281 |
215 attrs = keyTempl; | 282 attrs = keyTempl; |
216 PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; | 283 PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; |
217 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; | 284 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; |
218 PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, | 285 PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, |
219 params->prime.len); attrs++; | 286 params->prime.len); attrs++; |
220 PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, | 287 PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, |
221 params->subPrime.len); attrs++; | 288 params->subPrime.len); attrs++; |
222 PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++; | 289 if (params->base.len) { |
| 290 PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); |
| 291 » attrs++; |
| 292 } |
223 PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; | 293 PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; |
224 if (vfy) { | 294 if (vfy) { |
225 » counter = vfy->counter; | 295 » if (vfy->counter != -1) { |
226 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, | 296 » counter = vfy->counter; |
| 297 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, |
227 &counter, sizeof(counter)); attrs++; | 298 &counter, sizeof(counter)); attrs++; |
| 299 } |
228 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, | 300 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, |
229 vfy->seed.data, vfy->seed.len); attrs++; | 301 vfy->seed.data, vfy->seed.len); attrs++; |
230 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, | 302 » if (vfy->h.len) { |
| 303 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, |
231 vfy->h.data, vfy->h.len); attrs++; | 304 vfy->h.data, vfy->h.len); attrs++; |
| 305 } |
232 } | 306 } |
233 | 307 |
234 keyCount = attrs - keyTempl; | 308 keyCount = attrs - keyTempl; |
235 PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); | 309 PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); |
236 | 310 |
237 | 311 |
238 slot = PK11_GetInternalSlot(); | 312 slot = PK11_GetInternalSlot(); |
239 if (slot == NULL) { | 313 if (slot == NULL) { |
240 return SECFailure; | 314 return SECFailure; |
241 } | 315 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 503 |
430 | 504 |
431 /************************************************************************** | 505 /************************************************************************** |
432 * Fills in caller's "h" SECItem with the h value in verify. | 506 * Fills in caller's "h" SECItem with the h value in verify. |
433 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); | 507 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); |
434 **************************************************************************/ | 508 **************************************************************************/ |
435 extern SECStatus | 509 extern SECStatus |
436 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) { | 510 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) { |
437 return SECITEM_CopyItem(NULL, h, &verify->h); | 511 return SECITEM_CopyItem(NULL, h, &verify->h); |
438 } | 512 } |
OLD | NEW |