| 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 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, |
| 104 CKM_DSA_PARAMETER_GEN, &mechanism_info); |
| 105 /* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the |
| 106 * mechanism List. If we get a failure asking for this value, we know |
| 107 * it can't handle DSA2 */ |
| 108 if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) { |
| 109 PK11_FreeSlot(slot); |
| 110 slot = PK11_GetBestSlotWithKeySize(CKM_DSA_PARAMETER_GEN, |
| 111 primeBits, NULL); |
| 112 if (slot == NULL) { |
| 113 PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */ |
| 114 goto loser; |
| 115 } |
| 116 /* ditch seedBits in this case, they are NSS specific and at |
| 117 * this point we have a token that claims to handle DSA2 */ |
| 118 if (seedBits) { |
| 119 attrs--; |
| 120 } |
| 121 } |
| 122 } |
| 123 |
| 73 /* Initialize the Key Gen Mechanism */ | 124 /* Initialize the Key Gen Mechanism */ |
| 74 mechanism.mechanism = CKM_DSA_PARAMETER_GEN; | 125 mechanism.mechanism = CKM_DSA_PARAMETER_GEN; |
| 75 mechanism.pParameter = NULL; | 126 mechanism.pParameter = NULL; |
| 76 mechanism.ulParameterLen = 0; | 127 mechanism.ulParameterLen = 0; |
| 77 | 128 |
| 78 PK11_EnterSlotMonitor(slot); | 129 PK11_EnterSlotMonitor(slot); |
| 79 crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, | 130 crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, |
| 80 &mechanism, genTemplate, count, &objectID); | 131 &mechanism, genTemplate, count, &objectID); |
| 81 PK11_ExitSlotMonitor(slot); | 132 PK11_ExitSlotMonitor(slot); |
| 82 | 133 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 if (varena != NULL) { | 210 if (varena != NULL) { |
| 160 PORT_FreeArena(varena,PR_FALSE); | 211 PORT_FreeArena(varena,PR_FALSE); |
| 161 } | 212 } |
| 162 if (slot) { | 213 if (slot) { |
| 163 PK11_FreeSlot(slot); | 214 PK11_FreeSlot(slot); |
| 164 } | 215 } |
| 165 return SECFailure; | 216 return SECFailure; |
| 166 } | 217 } |
| 167 | 218 |
| 168 /* Generate PQGParams and PQGVerify structs. | 219 /* Generate PQGParams and PQGVerify structs. |
| 220 * Length of P specified by j. Length of h will match length of P. |
| 221 * Length of SEED in bytes specified in seedBytes. |
| 222 * seedBbytes must be in the range [20..255] or an error will result. |
| 223 */ |
| 224 extern SECStatus |
| 225 PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, |
| 226 PQGParams **pParams, PQGVerify **pVfy) |
| 227 { |
| 228 unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
| 229 return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy); |
| 230 } |
| 231 |
| 232 /* Generate PQGParams and PQGVerify structs. |
| 169 * Length of seed and length of h both equal length of P. | 233 * Length of seed and length of h both equal length of P. |
| 170 * All lengths are specified by "j", according to the table above. | 234 * All lengths are specified by "j", according to the table above. |
| 171 */ | 235 */ |
| 172 extern SECStatus | 236 extern SECStatus |
| 173 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) | 237 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) |
| 174 { | 238 { |
| 175 return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy); | 239 unsigned int primeBits = PQG_INDEX_TO_PBITS(j); |
| 240 return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy); |
| 176 } | 241 } |
| 177 | 242 |
| 178 /* Test PQGParams for validity as DSS PQG values. | 243 /* Test PQGParams for validity as DSS PQG values. |
| 179 * If vfy is non-NULL, test PQGParams to make sure they were generated | 244 * If vfy is non-NULL, test PQGParams to make sure they were generated |
| 180 * using the specified seed, counter, and h values. | 245 * using the specified seed, counter, and h values. |
| 181 * | 246 * |
| 182 * Return value indicates whether Verification operation ran successfully | 247 * Return value indicates whether Verification operation ran successfully |
| 183 * to completion, but does not indicate if PQGParams are valid or not. | 248 * to completion, but does not indicate if PQGParams are valid or not. |
| 184 * If return value is SECSuccess, then *pResult has these meanings: | 249 * If return value is SECSuccess, then *pResult has these meanings: |
| 185 * SECSuccess: PQGParams are valid. | 250 * SECSuccess: PQGParams are valid. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 212 CK_ULONG counter; | 277 CK_ULONG counter; |
| 213 CK_RV crv; | 278 CK_RV crv; |
| 214 | 279 |
| 215 attrs = keyTempl; | 280 attrs = keyTempl; |
| 216 PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; | 281 PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; |
| 217 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; | 282 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; |
| 218 PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, | 283 PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, |
| 219 params->prime.len); attrs++; | 284 params->prime.len); attrs++; |
| 220 PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, | 285 PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, |
| 221 params->subPrime.len); attrs++; | 286 params->subPrime.len); attrs++; |
| 222 PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++; | 287 if (params->base.len) { |
| 288 PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); |
| 289 » attrs++; |
| 290 } |
| 223 PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; | 291 PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; |
| 224 if (vfy) { | 292 if (vfy) { |
| 225 » counter = vfy->counter; | 293 » if (vfy->counter != -1) { |
| 226 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, | 294 » counter = vfy->counter; |
| 295 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, |
| 227 &counter, sizeof(counter)); attrs++; | 296 &counter, sizeof(counter)); attrs++; |
| 297 } |
| 228 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, | 298 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, |
| 229 vfy->seed.data, vfy->seed.len); attrs++; | 299 vfy->seed.data, vfy->seed.len); attrs++; |
| 230 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, | 300 » if (vfy->h.len) { |
| 301 » PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, |
| 231 vfy->h.data, vfy->h.len); attrs++; | 302 vfy->h.data, vfy->h.len); attrs++; |
| 303 } |
| 232 } | 304 } |
| 233 | 305 |
| 234 keyCount = attrs - keyTempl; | 306 keyCount = attrs - keyTempl; |
| 235 PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); | 307 PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); |
| 236 | 308 |
| 237 | 309 |
| 238 slot = PK11_GetInternalSlot(); | 310 slot = PK11_GetInternalSlot(); |
| 239 if (slot == NULL) { | 311 if (slot == NULL) { |
| 240 return SECFailure; | 312 return SECFailure; |
| 241 } | 313 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 | 501 |
| 430 | 502 |
| 431 /************************************************************************** | 503 /************************************************************************** |
| 432 * Fills in caller's "h" SECItem with the h value in verify. | 504 * Fills in caller's "h" SECItem with the h value in verify. |
| 433 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); | 505 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); |
| 434 **************************************************************************/ | 506 **************************************************************************/ |
| 435 extern SECStatus | 507 extern SECStatus |
| 436 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) { | 508 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) { |
| 437 return SECITEM_CopyItem(NULL, h, &verify->h); | 509 return SECITEM_CopyItem(NULL, h, &verify->h); |
| 438 } | 510 } |
| OLD | NEW |