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