Back to index

lightning-sunbird  0.9+nobinonly
pk11pqg.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 /* Thse functions are stub functions which will get replaced with calls through
00037  * PKCS #11.
00038  */
00039 
00040 #include "pk11func.h"
00041 #include "secmod.h"
00042 #include "secmodi.h"
00043 #include "secmodti.h"
00044 #include "pkcs11t.h"
00045 #include "pk11pqg.h"
00046 #include "pqgutil.h"
00047 #include "secerr.h"
00048 
00049 
00050 /* Generate PQGParams and PQGVerify structs.
00051  * Length of P specified by j.  Length of h will match length of P.
00052  * Length of SEED in bytes specified in seedBytes.
00053  * seedBbytes must be in the range [20..255] or an error will result.
00054  */
00055 extern SECStatus
00056 PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
00057                              PQGParams **pParams, PQGVerify **pVfy)
00058 {
00059     PK11SlotInfo *slot = NULL;
00060     CK_ATTRIBUTE genTemplate[5];
00061     CK_ATTRIBUTE *attrs = genTemplate;
00062     int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
00063     CK_MECHANISM mechanism;
00064     CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE;
00065     CK_RV crv;
00066     CK_ATTRIBUTE pTemplate[] = {
00067        { CKA_PRIME, NULL, 0 },
00068        { CKA_SUBPRIME, NULL, 0 },
00069        { CKA_BASE, NULL, 0 },
00070     };
00071     CK_ATTRIBUTE vTemplate[] = {
00072        { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
00073        { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
00074        { CKA_NETSCAPE_PQG_H, NULL, 0 },
00075     };
00076     int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]);
00077     int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]);
00078     PRArenaPool *parena = NULL;
00079     PRArenaPool *varena = NULL;
00080     PQGParams *params = NULL;
00081     PQGVerify *verify = NULL;
00082     CK_ULONG primeBits = PQG_INDEX_TO_PBITS(j);
00083     CK_ULONG seedBits = seedBytes*8;
00084 
00085     *pParams = NULL;
00086     *pVfy =  NULL;
00087 
00088     if (primeBits == (CK_ULONG)-1) {
00089        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00090        goto loser;
00091     }
00092     PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++;
00093     if (seedBits != 0) {
00094        PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, 
00095                                    &seedBits, sizeof(seedBits)); attrs++;
00096     }
00097     count = attrs - genTemplate;
00098     PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
00099 
00100     slot = PK11_GetInternalSlot();
00101     if (slot == NULL) {
00102        /* set error */
00103        goto loser;
00104     }
00105 
00106     /* Initialize the Key Gen Mechanism */
00107     mechanism.mechanism = CKM_DSA_PARAMETER_GEN;
00108     mechanism.pParameter = NULL;
00109     mechanism.ulParameterLen = 0;
00110 
00111     PK11_EnterSlotMonitor(slot);
00112     crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session,
00113                       &mechanism, genTemplate, count, &objectID);
00114     PK11_ExitSlotMonitor(slot);
00115 
00116     if (crv != CKR_OK) {
00117        PORT_SetError( PK11_MapError(crv) );
00118        goto loser;
00119     }
00120 
00121     parena = PORT_NewArena(60);
00122     if (!parena) {
00123        goto loser;
00124     }        
00125 
00126     crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount);
00127     if (crv != CKR_OK) {
00128        PORT_SetError( PK11_MapError(crv) );
00129        goto loser;
00130     }
00131 
00132 
00133     params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams));
00134     if (params == NULL) {
00135        goto loser;
00136     }
00137 
00138     /* fill in Params */
00139     params->arena = parena;
00140     params->prime.type = siUnsignedInteger;
00141     params->prime.data = pTemplate[0].pValue;
00142     params->prime.len = pTemplate[0].ulValueLen;
00143     params->subPrime.type = siUnsignedInteger;
00144     params->subPrime.data = pTemplate[1].pValue;
00145     params->subPrime.len = pTemplate[1].ulValueLen;
00146     params->base.type = siUnsignedInteger;
00147     params->base.data = pTemplate[2].pValue;
00148     params->base.len = pTemplate[2].ulValueLen;
00149 
00150 
00151     varena = PORT_NewArena(60);
00152     if (!varena) {
00153        goto loser;
00154     }        
00155 
00156     crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount);
00157     if (crv != CKR_OK) {
00158        PORT_SetError( PK11_MapError(crv) );
00159        goto loser;
00160     }
00161 
00162 
00163     verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify));
00164     if (verify == NULL) {
00165        goto loser;
00166     }
00167     /* fill in Params */
00168     verify->arena = varena;
00169     verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue);
00170     verify->seed.type = siUnsignedInteger;
00171     verify->seed.data = vTemplate[1].pValue;
00172     verify->seed.len = vTemplate[1].ulValueLen;
00173     verify->h.type = siUnsignedInteger;
00174     verify->h.data = vTemplate[2].pValue;
00175     verify->h.len = vTemplate[2].ulValueLen;
00176 
00177     PK11_DestroyObject(slot,objectID);
00178     PK11_FreeSlot(slot);
00179 
00180     *pParams = params;
00181     *pVfy =  verify;
00182 
00183     return SECSuccess;
00184 
00185 loser:
00186     if (objectID != CK_INVALID_HANDLE) {
00187        PK11_DestroyObject(slot,objectID);
00188     }
00189     if (parena != NULL) {
00190        PORT_FreeArena(parena,PR_FALSE);
00191     }
00192     if (varena != NULL) {
00193        PORT_FreeArena(varena,PR_FALSE);
00194     }
00195     if (slot) {
00196        PK11_FreeSlot(slot);
00197     }
00198     return SECFailure;
00199 }
00200 
00201 /* Generate PQGParams and PQGVerify structs.
00202  * Length of seed and length of h both equal length of P. 
00203  * All lengths are specified by "j", according to the table above.
00204  */
00205 extern SECStatus
00206 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
00207 {
00208     return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy);
00209 }
00210 
00211 /*  Test PQGParams for validity as DSS PQG values.
00212  *  If vfy is non-NULL, test PQGParams to make sure they were generated
00213  *       using the specified seed, counter, and h values.
00214  *
00215  *  Return value indicates whether Verification operation ran succesfully
00216  *  to completion, but does not indicate if PQGParams are valid or not.
00217  *  If return value is SECSuccess, then *pResult has these meanings:
00218  *       SECSuccess: PQGParams are valid.
00219  *       SECFailure: PQGParams are invalid.
00220  */
00221 
00222 extern SECStatus
00223 PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy, 
00224                                                  SECStatus *result)
00225 {
00226     CK_ATTRIBUTE keyTempl[] = {
00227        { CKA_CLASS, NULL, 0 },
00228        { CKA_KEY_TYPE, NULL, 0 },
00229        { CKA_PRIME, NULL, 0 },
00230        { CKA_SUBPRIME, NULL, 0 },
00231        { CKA_BASE, NULL, 0 },
00232        { CKA_TOKEN, NULL, 0 },
00233        { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
00234        { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
00235        { CKA_NETSCAPE_PQG_H, NULL, 0 },
00236     };
00237     CK_ATTRIBUTE *attrs;
00238     CK_BBOOL ckfalse = CK_FALSE;
00239     CK_OBJECT_CLASS class = CKO_KG_PARAMETERS;
00240     CK_KEY_TYPE keyType = CKK_DSA;
00241     SECStatus rv = SECSuccess;
00242     PK11SlotInfo *slot;
00243     int keyCount;
00244     CK_OBJECT_HANDLE objectID;
00245     CK_ULONG counter;
00246     CK_RV crv;
00247 
00248     attrs = keyTempl;
00249     PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++;
00250     PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
00251     PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, 
00252                                           params->prime.len); attrs++;
00253     PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, 
00254                                           params->subPrime.len); attrs++;
00255     PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++;
00256     PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++;
00257     if (vfy) {
00258        counter = vfy->counter;
00259        PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, 
00260                      &counter, sizeof(counter)); attrs++;
00261        PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, 
00262                      vfy->seed.data, vfy->seed.len); attrs++;
00263        PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, 
00264                      vfy->h.data, vfy->h.len); attrs++;
00265     }
00266 
00267     keyCount = attrs - keyTempl;
00268     PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0]));
00269 
00270 
00271     slot = PK11_GetInternalSlot();
00272     if (slot == NULL) {
00273        return SECFailure;
00274     }
00275 
00276     PK11_EnterSlotMonitor(slot);
00277     crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount, 
00278                                                         &objectID);
00279     PK11_ExitSlotMonitor(slot);
00280 
00281     /* throw away the keys, we only wanted the return code */
00282     PK11_DestroyObject(slot,objectID);
00283     PK11_FreeSlot(slot);
00284 
00285     *result = SECSuccess;
00286     if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
00287        *result = SECFailure;
00288     } else if (crv != CKR_OK) {
00289        PORT_SetError( PK11_MapError(crv) );
00290        rv = SECFailure;
00291     }
00292     return rv;
00293 
00294 }
00295 
00296 
00297 
00298 /**************************************************************************
00299  *  Free the PQGParams struct and the things it points to.                *
00300  **************************************************************************/
00301 extern void 
00302 PK11_PQG_DestroyParams(PQGParams *params) {
00303      PQG_DestroyParams(params);
00304      return;
00305 }
00306 
00307 /**************************************************************************
00308  *  Free the PQGVerify struct and the things it points to.                *
00309  **************************************************************************/
00310 extern void
00311 PK11_PQG_DestroyVerify(PQGVerify *vfy) {
00312     PQG_DestroyVerify(vfy);
00313     return;
00314 }
00315 
00316 /**************************************************************************
00317  *  Return a pointer to a new PQGParams struct that is constructed from   *
00318  *  copies of the arguments passed in.                                    *
00319  *  Return NULL on failure.                                               *
00320  **************************************************************************/
00321 extern PQGParams *
00322 PK11_PQG_NewParams(const SECItem * prime, const SECItem * subPrime, 
00323                                           const SECItem * base) {
00324     return PQG_NewParams(prime, subPrime, base);
00325 }
00326 
00327 
00328 /**************************************************************************
00329  * Fills in caller's "prime" SECItem with the prime value in params.
00330  * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);       
00331  **************************************************************************/
00332 extern SECStatus 
00333 PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem * prime) {
00334     return PQG_GetPrimeFromParams(params, prime);
00335 }
00336 
00337 
00338 /**************************************************************************
00339  * Fills in caller's "subPrime" SECItem with the prime value in params.
00340  * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);    
00341  **************************************************************************/
00342 extern SECStatus
00343 PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem * subPrime) {
00344     return PQG_GetSubPrimeFromParams(params, subPrime);
00345 }
00346 
00347 
00348 /**************************************************************************
00349  * Fills in caller's "base" SECItem with the base value in params.
00350  * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE); 
00351  **************************************************************************/
00352 extern SECStatus 
00353 PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) {
00354     return PQG_GetBaseFromParams(params, base);
00355 }
00356 
00357 
00358 /**************************************************************************
00359  *  Return a pointer to a new PQGVerify struct that is constructed from   *
00360  *  copies of the arguments passed in.                                    *
00361  *  Return NULL on failure.                                               *
00362  **************************************************************************/
00363 extern PQGVerify *
00364 PK11_PQG_NewVerify(unsigned int counter, const SECItem * seed, 
00365                                                  const SECItem * h) {
00366     return PQG_NewVerify(counter, seed, h);
00367 }
00368 
00369 
00370 /**************************************************************************
00371  * Returns "counter" value from the PQGVerify.
00372  **************************************************************************/
00373 extern unsigned int 
00374 PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) {
00375     return PQG_GetCounterFromVerify(verify);
00376 }
00377 
00378 /**************************************************************************
00379  * Fills in caller's "seed" SECItem with the seed value in verify.
00380  * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE); 
00381  **************************************************************************/
00382 extern SECStatus 
00383 PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) {
00384     return PQG_GetSeedFromVerify(verify, seed);
00385 }
00386 
00387 
00388 /**************************************************************************
00389  * Fills in caller's "h" SECItem with the h value in verify.
00390  * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);    
00391  **************************************************************************/
00392 extern SECStatus 
00393 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) {
00394     return PQG_GetHFromVerify(verify, h);
00395 }