diff options
author | relyea%netscape.com <devnull@localhost> | 2002-03-02 00:53:11 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2002-03-02 00:53:11 +0000 |
commit | 3e0ed94b51f713889758c51dee7730c103118e39 (patch) | |
tree | 376900271e53e2f5277cf345d11d15ef4265b32b | |
parent | 133799d1c04dfd27483a514bfe5d9bec1fbc1a64 (diff) | |
download | nss-hg-3e0ed94b51f713889758c51dee7730c103118e39.tar.gz |
Implement PQG Generate and Verify.
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pqg.c | 249 |
1 files changed, 210 insertions, 39 deletions
diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c index 530548c36..a7600ddb1 100644 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ b/security/nss/lib/pk11wrap/pk11pqg.c @@ -34,20 +34,13 @@ * PKCS #11. */ +#include "pk11func.h" +#include "secmod.h" +#include "secmodi.h" +#include "pkcs11t.h" #include "pk11pqg.h" +#include "secerr.h" -/* Generate PQGParams and PQGVerify structs. - * Length of seed and length of h both equal length of P. - * All lengths are specified by "j", according to the table above. - */ -extern SECStatus -PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) { -#ifdef notdef - return PQG_ParamGen(j, pParams, pVfy); -#else - return SECFailure; -#endif -} /* Generate PQGParams and PQGVerify structs. * Length of P specified by j. Length of h will match length of P. @@ -56,12 +49,142 @@ PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) { */ extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, - PQGParams **pParams, PQGVerify **pVfy) { -#ifdef notdef - return PQG_ParamGenSeedLen(j, seedBytes, pParams, pVfy); -#else + PQGParams **pParams, PQGVerify **pVfy) +{ + PK11SlotInfo *slot = NULL; + CK_ATTRIBUTE genTemplate[5]; + CK_ATTRIBUTE *attrs = genTemplate; + int count = sizeof(genTemplate)/sizeof(genTemplate[0]); + CK_MECHANISM mechanism; + CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; + CK_RV crv; + CK_BBOOL cktrue = CK_TRUE; + CK_ATTRIBUTE pTemplate[] = { + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + }; + CK_ATTRIBUTE vTemplate[] = { + { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, + { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, + { CKA_NETSCAPE_PQG_H, NULL, 0 }, + }; + int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]); + int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]); + PRArenaPool *parena = NULL; + PRArenaPool *varena = NULL; + PQGParams *params = NULL; + PQGVerify *verify = NULL; + CK_ULONG primeBits = j; + CK_ULONG seedBits = seedBytes*8; + + *pParams = NULL; + *pVfy = NULL; + + PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++; + if (seedBits != 0) { + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, + &seedBits, sizeof(seedBits)); attrs++; + } + count = attrs - genTemplate; + PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); + + slot = PK11_GetInternalSlot(); + if (slot == NULL) { + /* set error */ + goto loser; + } + + /* Initialize the Key Gen Mechanism */ + mechanism.mechanism = CKM_DSA_PARAMETER_GEN; + mechanism.pParameter = NULL; + mechanism.ulParameterLen = 0; + + PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, + &mechanism, genTemplate, count, &objectID); + PK11_ExitSlotMonitor(slot); + + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + parena = PORT_NewArena(60); + crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + + params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams)); + if (params == NULL) { + goto loser; + } + + /* fill in Params */ + params->arena = parena; + params->prime.data = pTemplate[0].pValue; + params->prime.len = pTemplate[0].ulValueLen; + params->subPrime.data = pTemplate[1].pValue; + params->subPrime.len = pTemplate[1].ulValueLen; + params->base.data = pTemplate[2].pValue; + params->base.len = pTemplate[2].ulValueLen; + + + varena = PORT_NewArena(60); + crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + + verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify)); + if (verify == NULL) { + goto loser; + } + /* fill in Params */ + verify->arena = varena; + verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue); + verify->seed.data = vTemplate[1].pValue; + verify->seed.len = vTemplate[1].ulValueLen; + verify->h.data = vTemplate[2].pValue; + verify->h.len = vTemplate[2].ulValueLen; + + PK11_DestroyObject(slot,objectID); + PK11_FreeSlot(slot); + + *pParams = params; + *pVfy = verify; + + return SECSuccess; + +loser: + if (objectID != CK_INVALID_HANDLE) { + PK11_DestroyObject(slot,objectID); + } + if (parena != NULL) { + PORT_FreeArena(parena,PR_FALSE); + } + if (varena != NULL) { + PORT_FreeArena(varena,PR_FALSE); + } + if (slot) { + PK11_FreeSlot(slot); + } return SECFailure; -#endif +} + +/* Generate PQGParams and PQGVerify structs. + * Length of seed and length of h both equal length of P. + * All lengths are specified by "j", according to the table above. + */ +extern SECStatus +PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) +{ + return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy); } /* Test PQGParams for validity as DSS PQG values. @@ -73,31 +196,79 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, * If return value is SECSuccess, then *pResult has these meanings: * SECSuccess: PQGParams are valid. * SECFailure: PQGParams are invalid. - * - * Verify the following 12 facts about PQG counter SEED g and h - * 1. Q is 160 bits long. - * 2. P is one of the 9 valid lengths. - * 3. G < P - * 4. P % Q == 1 - * 5. Q is prime - * 6. P is prime - * Steps 7-12 are done only if the optional PQGVerify is supplied. - * 7. counter < 4096 - * 8. g >= 160 and g < 2048 (g is length of seed in bits) - * 9. Q generated from SEED matches Q in PQGParams. - * 10. P generated from (L, counter, g, SEED, Q) matches P in PQGParams. - * 11. 1 < h < P-1 - * 12. G generated from h matches G in PQGParams. */ extern SECStatus -PK11_PQG_VerifyParams(const PQGParams *params, - const PQGVerify *vfy, SECStatus *result) { -#ifdef notdef - return PQG_VerifyParams(params, vfy, result); -#else - return SECFailure; -#endif +PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy, + SECStatus *result) +{ + CK_ATTRIBUTE keyTempl[] = { + { CKA_CLASS, NULL, 0 }, + { CKA_KEY_TYPE, NULL, 0 }, + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + { CKA_TOKEN, NULL, 0 }, + { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, + { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, + { CKA_NETSCAPE_PQG_H, NULL, 0 }, + }; + CK_ATTRIBUTE *attrs; + CK_BBOOL ckfalse = CK_FALSE; + CK_OBJECT_CLASS class = CKO_KG_PARAMETERS; + CK_KEY_TYPE keyType = CKK_DSA; + SECStatus rv = SECSuccess; + PK11SlotInfo *slot; + int keyCount; + CK_OBJECT_HANDLE objectID; + CK_ULONG counter; + CK_RV crv; + + attrs = keyTempl; + PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; + PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; + PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, + params->prime.len); attrs++; + PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, + params->subPrime.len); attrs++; + PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; + if (vfy) { + counter = vfy->counter; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, + &counter, sizeof(counter)); attrs++; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, + vfy->seed.data, vfy->seed.len); attrs++; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, + vfy->h.data, vfy->h.len); attrs++; + } + + keyCount = attrs - keyTempl; + PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); + + + slot = PK11_GetInternalSlot(); + if (slot == NULL) { + return SECFailure; + } + + PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount, + &objectID); + PK11_ExitSlotMonitor(slot); + + /* throw away the keys, we only wanted the return code */ + PK11_DestroyObject(slot,objectID); + PK11_FreeSlot(slot); + + if (crv == CKR_ATTRIBUTE_VALUE_INVALID) { + *result = SECFailure; + } else if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + rv = SECFailure; + } + return rv; + } |