Add support for Elliptic Curve Cryptography. Bug 195135.

Modified Files:
 	cmd/lib/SECerrs.h cmd/selfserv/selfserv.c
 	cmd/tstclnt/tstclnt.c lib/cryptohi/keyhi.h
 	lib/cryptohi/keythi.h lib/cryptohi/seckey.c
 	lib/cryptohi/secvfy.c lib/freebl/Makefile lib/freebl/blapi.h
 	lib/freebl/blapit.h lib/freebl/ldvector.c lib/freebl/loader.c
 	lib/freebl/loader.h lib/freebl/manifest.mn lib/nss/nss.def
 	lib/pk11wrap/pk11skey.c lib/pk11wrap/pk11slot.c
 	lib/softoken/lowkeyti.h lib/softoken/manifest.mn
 	lib/softoken/pkcs11.c lib/softoken/pkcs11c.c
 	lib/softoken/pkcs11t.h lib/ssl/ssl3con.c lib/ssl/ssl3prot.h
 	lib/ssl/sslcon.c lib/ssl/sslenum.c lib/ssl/sslimpl.h
 	lib/ssl/sslinfo.c lib/ssl/sslproto.h lib/ssl/sslsecur.c
 	lib/ssl/sslsock.c lib/ssl/sslt.h lib/util/secerr.h
 	lib/util/secoid.c lib/util/secoidt.h
Added Files:
 	lib/freebl/GFp_ecl.c lib/freebl/GFp_ecl.h lib/freebl/ec.c
 	lib/freebl/ec.h lib/softoken/ecdecode.c
This commit is contained in:
nelsonb%netscape.com 2003-02-27 01:31:38 +00:00
Родитель c5c0fb381e
Коммит 42fae25f24
40 изменённых файлов: 4875 добавлений и 75 удалений

Просмотреть файл

@ -460,3 +460,17 @@ ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
"You are attempting to import a cert with the same issuer/serial as \
an existing cert, but that is not the same cert.")
ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
"NSS could not shutdown. Objects are still in use.")
ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
"DER-encoded message contained extra usused data.")
ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
"Unsupported elliptic curve.")
ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
"Unsupported elliptic curve point form.")
ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
"Unrecognized Object IDentifier.")

Просмотреть файл

@ -15,8 +15,12 @@
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -101,6 +105,28 @@ const int ssl2CipherSuites[] = {
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
#ifdef NSS_ENABLE_ECC
/* NOTE: Since no new SSL2 ciphersuites are being
* invented, and we've run out of lowercase letters
* for SSL3 ciphers, we use letters G and beyond
* for new SSL3 ciphers. A -1 indicates the cipher
* is not currently implemented.
*/
-1, /* TLS_ECDH_ECDSA_WITH_NULL_SHA, * G */
-1, /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA, * H */
-1, /* TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, * I */
-1, /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, * J */
-1, /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, * K */
-1, /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, * L */
-1, /* TLS_ECDH_RSA_WITH_NULL_SHA, * M */
-1, /* TLS_ECDH_RSA_WITH_RC4_128_SHA, * N */
-1, /* TLS_ECDH_RSA_WITH_DES_CBC_SHA, * O */
-1, /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, * P */
-1, /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, * Q */
-1, /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, * R */
-1, /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, * S */
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* T */
#endif /* NSS_ENABLE_ECC */
0
};
@ -119,16 +145,16 @@ const int ssl3CipherSuites[] = {
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */
SSL_RSA_WITH_RC4_128_SHA, /* n */
TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */
SSL_DHE_RSA_WITH_DES_CBC_SHA, /* r */
SSL_DHE_DSS_WITH_DES_CBC_SHA, /* s */
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */
-1, /* TLS_DHE_DSS_WITH_RC4_128_SHA, * o */
-1, /* SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, * p */
-1, /* SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, * q */
-1, /* SSL_DHE_RSA_WITH_DES_CBC_SHA, * r */
-1, /* SSL_DHE_DSS_WITH_DES_CBC_SHA, * s */
-1, /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA, * t */
-1, /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA, * u */
TLS_RSA_WITH_AES_128_CBC_SHA, /* v */
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */
-1, /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA, * w */
-1, /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA, * x */
TLS_RSA_WITH_AES_256_CBC_SHA, /* y */
SSL_RSA_WITH_NULL_SHA, /* z */
0
@ -199,6 +225,9 @@ Usage(const char *progName)
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
#ifdef NSS_ENABLE_ECC
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"

Просмотреть файл

@ -15,8 +15,12 @@
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -74,6 +78,27 @@ int ssl2CipherSuites[] = {
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
#ifdef NSS_ENABLE_ECC
/* NOTE: Since no new SSL2 ciphersuites are being
* invented, and we've run out of lowercase letters
* for SSL3 ciphers, we use letters G and beyond
* for new SSL3 ciphers.
*/
TLS_ECDH_ECDSA_WITH_NULL_SHA, /* G */
TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* H */
TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, /* I */
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* J */
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* K */
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* L */
TLS_ECDH_RSA_WITH_NULL_SHA, /* M */
TLS_ECDH_RSA_WITH_RC4_128_SHA, /* N */
TLS_ECDH_RSA_WITH_DES_CBC_SHA, /* O */
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* P */
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* Q */
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* R */
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* S */
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* T */
#endif /* NSS_ENABLE_ECC */
0
};
@ -206,6 +231,22 @@ static void Usage(const char *progName)
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
#ifdef NSS_ENABLE_ECC
"G TLS ECDH ECDSA WITH NULL SHA\n"
"H TLS ECDH ECDSA WITH RC4 128 CBC SHA\n"
"I TLS ECDH ECDSA WITH DES CBC SHA\n"
"J TLS ECDH ECDSA WITH 3DES EDE CBC SHA\n"
"K TLS ECDH ECDSA WITH AES 128 CBC SHA\n"
"L TLS ECDH ECDSA WITH AES 256 CBC SHA\n"
"M TLS ECDH RSA WITH NULL SHA\n"
"N TLS ECDH RSA WITH RC4 128 CBC SHA\n"
"O TLS ECDH RSA WITH DES CBC SHA\n"
"P TLS ECDH RSA WITH 3DES EDE CBC SHA\n"
"Q TLS ECDH RSA WITH AES 128 CBC SHA\n"
"R TLS ECDH RSA WITH AES 256 CBC SHA\n"
"S TLS ECDHE ECDSA WITH AES 128 CBC SHA\n"
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -33,7 +37,7 @@
*
* key.h - public data structures and prototypes for the private key library
*
* $Id: keyhi.h,v 1.7 2002-02-03 03:37:17 relyea%netscape.com Exp $
* $Id: keyhi.h,v 1.8 2003-02-27 01:31:04 nelsonb%netscape.com Exp $
*/
#ifndef _KEYHI_H_
@ -79,10 +83,14 @@ extern SECStatus
SECKEY_KEAParamCompare(CERTCertificate *cert1,CERTCertificate *cert2);
/*
** Return the strength of the public key
** Return the strength of the public key in bytes
*/
extern unsigned SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk);
/*
** Return the strength of the public key in bits
*/
extern unsigned SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk);
/*
** Make a copy of the private key "privKey"
@ -110,6 +118,13 @@ SECKEYPrivateKey *SECKEY_CreateRSAPrivateKey(int keySizeInBits,
*/
SECKEYPrivateKey *SECKEY_CreateDHPrivateKey(SECKEYDHParams *param,
SECKEYPublicKey **pubk, void *cx);
/*
* create a new EC key pair. The private Key is returned...
*/
SECKEYPrivateKey *SECKEY_CreateECPrivateKey(SECKEYECParams *param,
SECKEYPublicKey **pubk, void *cx);
/*
** Create a subject-public-key-info based on a public key.
*/

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -44,7 +48,8 @@ typedef enum {
dsaKey = 2,
fortezzaKey = 3,
dhKey = 4,
keaKey = 5
keaKey = 5,
ecKey = 6
} KeyType;
/*
@ -117,6 +122,25 @@ struct SECKEYDHPublicKeyStr {
};
typedef struct SECKEYDHPublicKeyStr SECKEYDHPublicKey;
/*
** Elliptic curve Public Key structure
** The PKCS#11 layer needs DER encoding of ANSI X9.62
** parameters value
*/
typedef SECItem SECKEYECParams;
struct SECKEYECPublicKeyStr {
SECKEYECParams DEREncodedParams;
int size; /* size in bits */
SECItem publicValue; /* encoded point */
/* XXX Even though the PKCS#11 interface takes encoded parameters,
* we may still wish to decode them above PKCS#11 for things like
* printing key information. For named curves, which is what
* we initially support, we ought to have the curve name at the
* very least.
*/
};
typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey;
/*
** FORTEZZA Public Key structures
@ -173,6 +197,7 @@ struct SECKEYPublicKeyStr {
SECKEYDHPublicKey dh;
SECKEYKEAPublicKey kea;
SECKEYFortezzaPublicKey fortezza;
SECKEYECPublicKey ec;
} u;
};
typedef struct SECKEYPublicKeyStr SECKEYPublicKey;

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -44,6 +48,7 @@
#include "secerr.h"
#include "secdig.h"
#include "prtime.h"
#include "ec.h"
const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
@ -229,6 +234,33 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
return(privk);
}
/* Create an EC key pair in any slot able to do so,
** This is a "session" (temporary), not "token" (permanent) key.
** Because of the high probability that this key will need to be moved to
** another token, and the high cost of moving "sensitive" keys, we attempt
** to create this key pair without the "sensitive" attribute, but revert to
** creating a "sensitive" key if necessary.
*/
SECKEYPrivateKey *
SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx)
{
#ifdef NSS_ENABLE_ECC
SECKEYPrivateKey *privk;
PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN,cx);
privk = PK11_GenerateKeyPair(slot, CKM_EC_KEY_PAIR_GEN, param,
pubk, PR_FALSE, PR_FALSE, cx);
if (!privk)
privk = PK11_GenerateKeyPair(slot, CKM_EC_KEY_PAIR_GEN, param,
pubk, PR_FALSE, PR_TRUE, cx);
PK11_FreeSlot(slot);
return(privk);
#else
return NULL;
#endif /* NSS_ENABLE_ECC */
}
void
SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk)
{
@ -433,7 +465,8 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
(tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
(tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
(tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
(tag != SEC_OID_SDN702_DSA_SIGNATURE) ) {
(tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
(tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
return SECSuccess;
}
@ -480,8 +513,8 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
(tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
(tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
(tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
(tag != SEC_OID_SDN702_DSA_SIGNATURE) ) {
(tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
(tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
return SECFailure;
}
} else {
@ -881,12 +914,49 @@ CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki) {
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keyType = dhKey;
break;
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
keyType = ecKey;
break;
default:
keyType = nullKey;
}
return keyType;
}
#ifdef NSS_ENABLE_ECC
static int
seckey_supportedECParams(SECItem *encodedParams)
{
SECOidTag tag;
SECItem oid = { siBuffer, NULL, 0};
/* We do not currently support explicit DER encoding of curve
* parameters. Make sure the encoding takes the form of
* an object identifier (this is how named curves are encoded).
*/
if (encodedParams->data[0] != SEC_ASN1_OBJECT_ID) return 0;
/* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
* followed by the length of the curve oid and the curve oid.
*/
oid.len = encodedParams->data[1];
oid.data = encodedParams->data + 2;
tag = SECOID_FindOIDTag(&oid);
return (((tag >= SEC_OID_ANSIX962_EC_PRIME192V1)
&& (tag <= SEC_OID_ANSIX962_EC_PRIME256V1)) ||
((tag >= SEC_OID_SECG_EC_SECP112R1)
&& (tag <= SEC_OID_SECG_EC_SECP521R1)));
}
static int
seckey_supportedECPointForm(SECItem *ecPoint)
{
/* For now, we only support uncompressed points */
return (ecPoint->data[0] == EC_POINT_FORM_UNCOMPRESSED);
}
#endif /* NSS_ENABLE_ECC */
static SECKEYPublicKey *
seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
{
@ -1012,6 +1082,46 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
break;
#ifdef NSS_ENABLE_ECC
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
pubk->keyType = ecKey;
pubk->u.ec.size = 0;
#if 0
/* If we uncomment these checks, ssl3con.c produces an "SSL
* was unable to extract the public key from the peer's
* certificate" error upon encountering an EC certificate with
* an unsupported curve or point form. It isn't clear that we
* should be triggering this error because the EC key was
* *successfully extracted* even though we can't use
* it. Commenting these checks delays detection of unsupported
* curves to a later point in the handshake (e.g. when a
* client attempts to generate a key pair before sending the
* ClientKeyExchange message).
*/
if (!seckey_supportedECParams(&spki->algorithm.parameters)) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
rv = SECFailure;
break;
}
if (!seckey_supportedECPointForm(&newOs)) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
rv = SECFailure;
break;
}
#endif
/* Since PKCS#11 directly takes the DER encoding of EC params
* and public value, we don't need any decoding here.
*/
rv = SECITEM_CopyItem(arena, &pubk->u.ec.DEREncodedParams,
&spki->algorithm.parameters);
if ( rv != SECSuccess )
break;
rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
if (rv == SECSuccess) return pubk;
break;
#endif /* NSS_ENABLE_ECC */
default:
rv = SECFailure;
@ -1053,6 +1163,59 @@ CERT_KMIDPublicKey(CERTCertificate *cert)
return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);
}
#ifdef NSS_ENABLE_ECC
static int
seckey_ECParams2KeySize(SECItem *encodedParams)
{
SECOidTag tag;
SECItem oid = { siBuffer, NULL, 0};
/* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
* followed by the length of the curve oid and the curve oid.
*/
oid.len = encodedParams->data[1];
oid.data = encodedParams->data + 2;
if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
return 0;
switch (tag) {
case SEC_OID_ANSIX962_EC_PRIME192V1:
case SEC_OID_ANSIX962_EC_PRIME192V2:
case SEC_OID_ANSIX962_EC_PRIME192V3:
return 192;
case SEC_OID_ANSIX962_EC_PRIME239V1:
case SEC_OID_ANSIX962_EC_PRIME239V2:
case SEC_OID_ANSIX962_EC_PRIME239V3:
return 239;
case SEC_OID_ANSIX962_EC_PRIME256V1:
return 256;
case SEC_OID_SECG_EC_SECP112R1:
case SEC_OID_SECG_EC_SECP112R2:
return 112;
case SEC_OID_SECG_EC_SECP128R1:
case SEC_OID_SECG_EC_SECP128R2:
return 128;
case SEC_OID_SECG_EC_SECP160K1:
case SEC_OID_SECG_EC_SECP160R1:
case SEC_OID_SECG_EC_SECP160R2:
return 160;
case SEC_OID_SECG_EC_SECP192K1:
return 192;
case SEC_OID_SECG_EC_SECP224K1:
case SEC_OID_SECG_EC_SECP224R1:
return 224;
case SEC_OID_SECG_EC_SECP256K1:
return 256;
case SEC_OID_SECG_EC_SECP384R1:
return 384;
case SEC_OID_SECG_EC_SECP521R1:
return 521;
default:
return 0;
}
}
#endif /* NSS_ENABLE_ECC */
/* returns key strength in bytes (not bits) */
unsigned
SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
@ -1076,6 +1239,39 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
pubk->u.dh.publicValue.len - 1;
case fortezzaKey:
return PR_MAX(pubk->u.fortezza.KEAKey.len, pubk->u.fortezza.DSSKey.len);
#ifdef NSS_ENABLE_ECC
case ecKey:
/* Get the key size in bits and adjust */
if (pubk->u.ec.size == 0) {
pubk->u.ec.size =
seckey_ECParams2KeySize(&pubk->u.ec.DEREncodedParams);
}
return (pubk->u.ec.size + 7)/8;
#endif /* NSS_ENABLE_ECC */
default:
break;
}
return 0;
}
/* returns key strength in bits */
unsigned
SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
{
switch (pubk->keyType) {
case rsaKey:
case dsaKey:
case dhKey:
case fortezzaKey:
return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */
#ifdef NSS_ENABLE_ECC
case ecKey:
if (pubk->u.ec.size == 0) {
pubk->u.ec.size =
seckey_ECParams2KeySize(&pubk->u.ec.DEREncodedParams);
}
return pubk->u.ec.size;
#endif /* NSS_ENABLE_ECC */
default:
break;
}
@ -1230,6 +1426,16 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
&pubk->u.dh.publicValue);
break;
#ifdef NSS_ENABLE_ECC
case ecKey:
copyk->u.ec.size = pubk->u.ec.size;
rv = SECITEM_CopyItem(arena,&copyk->u.ec.DEREncodedParams,
&pubk->u.ec.DEREncodedParams);
if (rv != SECSuccess) break;
rv = SECITEM_CopyItem(arena,&copyk->u.ec.publicValue,
&pubk->u.ec.publicValue);
break;
#endif /* NSS_ENABLE_ECC */
case nullKey:
return copyk;
default:

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: secvfy.c,v 1.7 2002-12-12 06:05:17 nelsonb%netscape.com Exp $
* $Id: secvfy.c,v 1.8 2003-02-27 01:31:07 nelsonb%netscape.com Exp $
*/
#include <stdio.h>
@ -106,7 +110,7 @@ DecryptSigBlock(int *tagp, unsigned char *digest, SECKEYPublicKey *key,
return rv;
}
typedef enum { VFY_RSA, VFY_DSA} VerifyType;
typedef enum { VFY_RSA, VFY_DSA, VFY_ECDSA } VerifyType;
struct VFYContextStr {
SECOidTag alg;
@ -119,6 +123,7 @@ struct VFYContextStr {
const SECHashObject *hashobj;
SECOidTag sigAlg;
PRBool hasSignature;
unsigned char ecdsadigest[2 * MAX_ECKEY_LEN];
};
/*
@ -211,12 +216,60 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg)
return SECSuccess;
}
#ifdef NSS_ENABLE_ECC
/*
* decode the ECDSA signature from it's DER wrapping.
*/
static SECStatus
decodeECDSASignature(SECOidTag algid, SECItem *sig,
unsigned char *digest, int len)
{
SECStatus rv=SECSuccess;
if (len > MAX_ECKEY_LEN * 2) {
rv = SECFailure;
goto loser;
}
/* if this is a DER encoded signature, decode it first */
if (algid == SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST) {
/* XXX Use a better decoder */
if ((sig->len < len + 6) ||
(sig->data[0] != 0x30) || /* must start with a SEQUENCE */
(sig->data[1] != sig->len - 2) ||
(sig->data[2] != 0x02) || /* 1st INTEGER, r */
(sig->data[3] < len/2) ||
(sig->data[4 + sig->data[3]] != 0x02) || /* 2nd INTEGER, s */
(sig->data[5 + sig->data[3]] < len/2)) {
rv = SECFailure;
goto loser;
}
PORT_Memcpy(digest, sig->data + 4 + (sig->data[3]-len/2), len/2);
PORT_Memcpy(digest + len/2, sig->data + sig->len - len/2, len/2);
} else {
if (sig->len != len) {
rv = SECFailure;
goto loser;
}
PORT_Memcpy(digest, sig->data, sig->len);
}
loser:
if (rv == SECFailure) PORT_SetError(SEC_ERROR_BAD_DER);
return rv;
}
#endif /* NSS_ENABLE_ECC */
VFYContext *
VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
void *wincx)
{
VFYContext *cx;
SECStatus rv;
#ifdef NSS_ENABLE_ECC
int sigLen;
#endif /* NSS_ENABLE_ECC */
cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
if (cx) {
@ -246,6 +299,21 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
rv = decodeDSASignature(algid,sig,&cx->digest[0]);
}
break;
#ifdef NSS_ENABLE_ECC
case ecKey:
cx->type = VFY_ECDSA;
cx->alg = SEC_OID_SHA1;
cx->key = SECKEY_CopyPublicKey(key);
/* Unlike DSA, EDSA does not have a fixed signature length
* (it depends on the key size)
*/
sigLen = SECKEY_PublicKeyStrength(key) * 2;
if (sig) {
rv = decodeECDSASignature(algid,sig,&cx->ecdsadigest[0],
sigLen);
}
break;
#endif /* NSS_ENABLE_ECC */
default:
rv = SECFailure;
break;
@ -326,6 +394,9 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
unsigned part;
SECItem hash,dsasig;
SECStatus rv;
#ifdef NSS_ENABLE_ECC
SECItem ecdsasig;
#endif /* NSS_ENABLE_ECC */
if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -370,6 +441,28 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
return SECFailure;
}
break;
#ifdef NSS_ENABLE_ECC
case VFY_ECDSA:
if (sig) {
rv = decodeECDSASignature(cx->sigAlg,sig,&cx->ecdsadigest[0],
SECKEY_PublicKeyStrength(cx->key) * 2);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
}
ecdsasig.data = cx->ecdsadigest;
ecdsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2;
hash.data = final;
hash.len = part;
if (PK11_Verify(cx->key,&ecdsasig,&hash,cx->wincx) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
break;
#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure; /* shouldn't happen */

Просмотреть файл

@ -0,0 +1,647 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for prime
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Sheueling Chang Shantz <sheueling.chang@sun.com> and
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
* Nils Larsch <nla@trustcenter.de>, and
* Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifdef NSS_ENABLE_ECC
/*
* GFp_ecl.c: Contains an implementation of elliptic curve math library
* for curves over GFp.
*
* XXX Can be moved to a separate subdirectory later.
*
*/
#include "GFp_ecl.h"
#include "mpi/mplogic.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
mp_err
GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py)
{
if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
return MP_YES;
} else {
return MP_NO;
}
}
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
mp_err
GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py)
{
mp_zero(px);
mp_zero(py);
return MP_OKAY;
}
/* Computes R = P + Q based on IEEE P1363 A.10.1.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int lambda, temp, xtemp, ytemp;
CHECK_MPI_OK( mp_init(&lambda) );
CHECK_MPI_OK( mp_init(&temp) );
CHECK_MPI_OK( mp_init(&xtemp) );
CHECK_MPI_OK( mp_init(&ytemp) );
/* if P = inf, then R = Q */
if (GFp_ec_pt_is_inf_aff(px, py) == 0) {
CHECK_MPI_OK( mp_copy(qx, rx) );
CHECK_MPI_OK( mp_copy(qy, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if Q = inf, then R = P */
if (GFp_ec_pt_is_inf_aff(qx, qy) == 0) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
err = MP_OKAY;
goto cleanup;
}
/* if px != qx, then lambda = (py-qy) / (px-qx) */
if (mp_cmp(px, qx) != 0) {
CHECK_MPI_OK( mp_submod(py, qy, p, &ytemp) );
CHECK_MPI_OK( mp_submod(px, qx, p, &xtemp) );
CHECK_MPI_OK( mp_invmod(&xtemp, p, &xtemp) );
CHECK_MPI_OK( mp_mulmod(&ytemp, &xtemp, p, &lambda) );
} else {
/* if py != qy or qy = 0, then R = inf */
if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* lambda = (3qx^2+a) / (2qy) */
CHECK_MPI_OK( mp_sqrmod(qx, p, &xtemp) );
mp_set(&temp, 0x3);
CHECK_MPI_OK( mp_mulmod(&xtemp, &temp, p, &xtemp) );
CHECK_MPI_OK( mp_addmod(&xtemp, a, p, &xtemp) );
mp_set(&temp, 0x2);
CHECK_MPI_OK( mp_mulmod(qy, &temp, p, &ytemp) );
CHECK_MPI_OK( mp_invmod(&ytemp, p, &ytemp) );
CHECK_MPI_OK( mp_mulmod(&xtemp, &ytemp, p, &lambda) );
}
/* rx = lambda^2 - px - qx */
CHECK_MPI_OK( mp_sqrmod(&lambda, p, &xtemp) );
CHECK_MPI_OK( mp_submod(&xtemp, px, p, &xtemp) );
CHECK_MPI_OK( mp_submod(&xtemp, qx, p, &xtemp) );
/* ry = (x1-x2) * lambda - y1 */
CHECK_MPI_OK( mp_submod(qx, &xtemp, p, &ytemp) );
CHECK_MPI_OK( mp_mulmod(&ytemp, &lambda, p, &ytemp) );
CHECK_MPI_OK( mp_submod(&ytemp, qy, p, &ytemp) );
CHECK_MPI_OK( mp_copy(&xtemp, rx) );
CHECK_MPI_OK( mp_copy(&ytemp, ry) );
cleanup:
mp_clear(&lambda);
mp_clear(&temp);
mp_clear(&xtemp);
mp_clear(&ytemp);
return err;
}
/* Computes R = P - Q.
* Elliptic curve points P, Q, and R can all be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int nqy;
MP_DIGITS(&nqy) = 0;
CHECK_MPI_OK( mp_init(&nqy) );
/* nqy = -qy */
CHECK_MPI_OK( mp_neg(qy, &nqy) );
err = GFp_ec_pt_add_aff(p, a, px, py, qx, &nqy, rx, ry);
cleanup:
mp_clear(&nqy);
return err;
}
/* Computes R = 2P.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, mp_int *rx, mp_int *ry)
{
return GFp_ec_pt_add_aff(p, a, px, py, px, py, rx, ry);
}
/* Gets the i'th bit in the binary representation of a.
* If i >= length(a), then return 0.
* (The above behaviour differs from mpl_get_bit, which
* causes an error if i >= length(a).)
*/
#define MP_GET_BIT(a, i) \
((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
/* Computes R = nP based on IEEE P1363 A.10.3.
* Elliptic curve points P and R can be identical.
* Uses affine coordinates.
*/
mp_err
GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n, mp_int *rx,
mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int k, k3, qx, qy, sx, sy;
int b1, b3, i, l;
MP_DIGITS(&k) = 0;
MP_DIGITS(&k3) = 0;
MP_DIGITS(&qx) = 0;
MP_DIGITS(&qy) = 0;
MP_DIGITS(&sx) = 0;
MP_DIGITS(&sy) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&k3) );
CHECK_MPI_OK( mp_init(&qx) );
CHECK_MPI_OK( mp_init(&qy) );
CHECK_MPI_OK( mp_init(&sx) );
CHECK_MPI_OK( mp_init(&sy) );
/* if n = 0 then r = inf */
if (mp_cmp_z(n) == 0) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
}
/* Q = P, k = n */
CHECK_MPI_OK( mp_copy(px, &qx) );
CHECK_MPI_OK( mp_copy(py, &qy) );
CHECK_MPI_OK( mp_copy(n, &k) );
/* if n < 0 Q = -Q, k = -k */
if (mp_cmp_z(n) < 0) {
CHECK_MPI_OK( mp_neg(&qy, &qy) );
CHECK_MPI_OK( mp_mod(&qy, p, &qy) );
CHECK_MPI_OK( mp_neg(&k, &k) );
CHECK_MPI_OK( mp_mod(&k, p, &k) );
}
#ifdef EC_DEBUG /* basic double and add method */
l = mpl_significant_bits(&k) - 1;
mp_zero(&sx);
mp_zero(&sy);
for (i = l; i >= 0; i--) {
/* if k_i = 1, then S = S + Q */
if (mpl_get_bit(&k, i) != 0) {
CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
}
if (i > 0) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) );
}
}
#else /* double and add/subtract method from standard */
/* k3 = 3 * k */
mp_set(&k3, 0x3);
CHECK_MPI_OK( mp_mul(&k, &k3, &k3) );
/* S = Q */
CHECK_MPI_OK( mp_copy(&qx, &sx) );
CHECK_MPI_OK( mp_copy(&qy, &sy) );
/* l = index of high order bit in binary representation of 3*k */
l = mpl_significant_bits(&k3) - 1;
/* for i = l-1 downto 1 */
for (i = l - 1; i >= 1; i--) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) );
b3 = MP_GET_BIT(&k3, i);
b1 = MP_GET_BIT(&k, i);
/* if k3_i = 1 and k_i = 0, then S = S + Q */
if ((b3 == 1) && (b1 == 0)) {
CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
/* if k3_i = 0 and k_i = 1, then S = S - Q */
} else if ((b3 == 0) && (b1 == 1)) {
CHECK_MPI_OK( GFp_ec_pt_sub_aff(p, a, &sx, &sy,
&qx, &qy, &sx, &sy) );
}
}
#endif
/* output S */
CHECK_MPI_OK( mp_copy(&sx, rx) );
CHECK_MPI_OK( mp_copy(&sy, ry) );
cleanup:
mp_clear(&k);
mp_clear(&k3);
mp_clear(&qx);
mp_clear(&qy);
mp_clear(&sx);
mp_clear(&sy);
return err;
}
/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
* affine coordinates R(rx, ry). P and R can share x and y coordinates.
*/
mp_err
GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *p, mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int z1, z2, z3;
MP_DIGITS(&z1) = 0;
MP_DIGITS(&z2) = 0;
MP_DIGITS(&z3) = 0;
CHECK_MPI_OK( mp_init(&z1) );
CHECK_MPI_OK( mp_init(&z2) );
CHECK_MPI_OK( mp_init(&z3) );
/* if point at infinity, then set point at infinity and exit */
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( GFp_ec_pt_set_inf_aff(rx, ry) );
goto cleanup;
}
/* transform (px, py, pz) into (px / pz^2, py / pz^3) */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
} else {
CHECK_MPI_OK( mp_invmod(pz, p, &z1) );
CHECK_MPI_OK( mp_sqrmod(&z1, p, &z2) );
CHECK_MPI_OK( mp_mulmod(&z1, &z2, p, &z3) );
CHECK_MPI_OK( mp_mulmod(px, &z2, p, rx) );
CHECK_MPI_OK( mp_mulmod(py, &z3, p, ry) );
}
cleanup:
mp_clear(&z1);
mp_clear(&z2);
mp_clear(&z3);
return err;
}
/* Checks if point P(px, py, pz) is at infinity.
* Uses Jacobian coordinates.
*/
mp_err
GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
{
return mp_cmp_z(pz);
}
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
* coordinates.
*/
mp_err
GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
{
mp_zero(pz);
return MP_OKAY;
}
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and
* Q is (qx, qy, qz). Elliptic curve points P, Q, and R can all be
* identical. Uses Jacobian coordinates.
*
* This routine implements Point Addition in the Jacobian Projective
* space as described in the paper "Efficient elliptic curve exponentiation
* using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
*/
mp_err
GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *pz, const mp_int *qx,
const mp_int *qy, const mp_int *qz, mp_int *rx, mp_int *ry, mp_int *rz)
{
mp_err err = MP_OKAY;
mp_int n0, u1, u2, s1, s2, H, G;
MP_DIGITS(&n0) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&s1) = 0;
MP_DIGITS(&s2) = 0;
MP_DIGITS(&H) = 0;
MP_DIGITS(&G) = 0;
CHECK_MPI_OK( mp_init(&n0) );
CHECK_MPI_OK( mp_init(&u1) );
CHECK_MPI_OK( mp_init(&u2) );
CHECK_MPI_OK( mp_init(&s1) );
CHECK_MPI_OK( mp_init(&s2) );
CHECK_MPI_OK( mp_init(&H) );
CHECK_MPI_OK( mp_init(&G) );
/* Use point double if pointers are equal. */
if ((px == qx) && (py == qy) && (pz == qz)) {
err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, rx, ry, rz);
goto cleanup;
}
/* If either P or Q is the point at infinity, then return
* the other point
*/
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( mp_copy(qx, rx) );
CHECK_MPI_OK( mp_copy(qy, ry) );
CHECK_MPI_OK( mp_copy(qz, rz) );
goto cleanup;
}
if (GFp_ec_pt_is_inf_jac(qx, qy, qz) == MP_YES) {
CHECK_MPI_OK( mp_copy(px, rx) );
CHECK_MPI_OK( mp_copy(py, ry) );
CHECK_MPI_OK( mp_copy(pz, rz) );
goto cleanup;
}
/* Compute u1 = px * qz^2, s1 = py * qz^3 */
if (mp_cmp_d(qz, 1) == 0) {
CHECK_MPI_OK( mp_copy(px, &u1) );
CHECK_MPI_OK( mp_copy(py, &s1) );
} else {
CHECK_MPI_OK( mp_sqrmod(qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(px, &n0, p, &u1) );
CHECK_MPI_OK( mp_mulmod(&n0, qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(py, &n0, p, &s1) );
}
/* Compute u2 = qx * pz^2, s2 = qy * pz^3 */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_copy(qx, &u2) );
CHECK_MPI_OK( mp_copy(qy, &s2) );
} else {
CHECK_MPI_OK( mp_sqrmod(pz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(qx, &n0, p, &u2) );
CHECK_MPI_OK( mp_mulmod(&n0, pz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(qy, &n0, p, &s2) );
}
/* Compute H = u2 - u1 ; G = s2 - s1 */
CHECK_MPI_OK( mp_submod(&u2, &u1, p, &H) );
CHECK_MPI_OK( mp_submod(&s2, &s1, p, &G) );
if (mp_cmp_z(&H) == 0) {
if (mp_cmp_z(&G) == 0) {
/* P = Q; double */
err = GFp_ec_pt_dbl_jac(p, a, px, py, pz,
rx, ry, rz);
goto cleanup;
} else {
/* P = -Q; return point at infinity */
CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) );
goto cleanup;
}
}
/* rz = pz * qz * H */
if (mp_cmp_d(pz, 1) == 0) {
if (mp_cmp_d(qz, 1) == 0) {
/* if pz == qz == 1, then rz = H */
CHECK_MPI_OK( mp_copy(&H, rz) );
} else {
CHECK_MPI_OK( mp_mulmod(qz, &H, p, rz) );
}
} else {
if (mp_cmp_d(qz, 1) == 0) {
CHECK_MPI_OK( mp_mulmod(pz, &H, p, rz) );
} else {
CHECK_MPI_OK( mp_mulmod(pz, qz, p, &n0) );
CHECK_MPI_OK( mp_mulmod(&n0, &H, p, rz) );
}
}
/* rx = G^2 - H^3 - 2 * u1 * H^2 */
CHECK_MPI_OK( mp_sqrmod(&G, p, rx) );
CHECK_MPI_OK( mp_sqrmod(&H, p, &n0) );
CHECK_MPI_OK( mp_mulmod(&n0, &u1, p, &u1) );
CHECK_MPI_OK( mp_addmod(&u1, &u1, p, &u2) );
CHECK_MPI_OK( mp_mulmod(&H, &n0, p, &H) );
CHECK_MPI_OK( mp_submod(rx, &H, p, rx) );
CHECK_MPI_OK( mp_submod(rx, &u2, p, rx) );
/* ry = - s1 * H^3 + G * (u1 * H^2 - rx) */
/* (formula based on values of variables before block above) */
CHECK_MPI_OK( mp_submod(&u1, rx, p, &u1) );
CHECK_MPI_OK( mp_mulmod(&G, &u1, p, ry) );
CHECK_MPI_OK( mp_mulmod(&s1, &H, p, &s1) );
CHECK_MPI_OK( mp_submod(ry, &s1, p, ry) );
cleanup:
mp_clear(&n0);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&s1);
mp_clear(&s2);
mp_clear(&H);
mp_clear(&G);
return err;
}
/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
* Jacobian coordinates.
*
* This routine implements Point Doubling in the Jacobian Projective
* space as described in the paper "Efficient elliptic curve exponentiation
* using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
*/
mp_err
GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, const mp_int *px,
const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, mp_int *rz)
{
mp_err err = MP_OKAY;
mp_int t0, t1, M, S;
MP_DIGITS(&t0) = 0;
MP_DIGITS(&t1) = 0;
MP_DIGITS(&M) = 0;
MP_DIGITS(&S) = 0;
CHECK_MPI_OK( mp_init(&t0) );
CHECK_MPI_OK( mp_init(&t1) );
CHECK_MPI_OK( mp_init(&M) );
CHECK_MPI_OK( mp_init(&S) );
if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) {
CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) );
goto cleanup;
}
if (mp_cmp_d(pz, 1) == 0) {
/* M = 3 * px^2 + a */
CHECK_MPI_OK( mp_sqrmod(px, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, a, p, &M) );
} else if (mp_cmp_int(a, -3) == 0) {
/* M = 3 * (px + pz^2) * (px - pz) */
CHECK_MPI_OK( mp_sqrmod(pz, p, &M) );
CHECK_MPI_OK( mp_addmod(px, &M, p, &t0) );
CHECK_MPI_OK( mp_submod(px, &M, p, &t1) );
CHECK_MPI_OK( mp_mulmod(&t0, &t1, p, &M) );
CHECK_MPI_OK( mp_addmod(&M, &M, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &M) );
} else {
CHECK_MPI_OK( mp_sqrmod(px, p, &t0) );
CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) );
CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) );
CHECK_MPI_OK( mp_sqrmod(pz, p, &M) );
CHECK_MPI_OK( mp_sqrmod(&M, p, &M) );
CHECK_MPI_OK( mp_mulmod(&M, a, p, &M) );
CHECK_MPI_OK( mp_addmod(&M, &t0, p, &M) );
}
/* rz = 2 * py * pz */
if (mp_cmp_d(pz, 1) == 0) {
CHECK_MPI_OK( mp_addmod(py, py, p, rz) );
CHECK_MPI_OK( mp_sqrmod(rz, p, &t0) );
} else {
CHECK_MPI_OK( mp_addmod(py, py, p, &t0) );
CHECK_MPI_OK( mp_mulmod(&t0, pz, p, rz) );
CHECK_MPI_OK( mp_sqrmod(&t0, p, &t0) );
}
/* S = 4 * px * py^2 = pz * (2 * py)^2 */
CHECK_MPI_OK( mp_mulmod(px, &t0, p, &S) );
/* rx = M^2 - 2 * S */
CHECK_MPI_OK( mp_addmod(&S, &S, p, &t1) );
CHECK_MPI_OK( mp_sqrmod(&M, p, rx) );
CHECK_MPI_OK( mp_submod(rx, &t1, p, rx) );
/* ry = M * (S - rx) - 8 * py^4 */
CHECK_MPI_OK( mp_sqrmod(&t0, p, &t1) );
if (mp_isodd(&t1)) {
CHECK_MPI_OK( mp_add(&t1, p, &t1) );
}
CHECK_MPI_OK( mp_div_2(&t1, &t1) );
CHECK_MPI_OK( mp_submod(&S, rx, p, &S) );
CHECK_MPI_OK( mp_mulmod(&M, &S, p, &M) );
CHECK_MPI_OK( mp_submod(&M, &t1, p, ry) );
cleanup:
mp_clear(&t0);
mp_clear(&t1);
mp_clear(&M);
mp_clear(&S);
return err;
}
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Elliptic curve points P and R can be
* identical. Uses Jacobian coordinates.
*/
mp_err
GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry)
{
mp_err err = MP_OKAY;
mp_int k, qx, qy, qz, sx, sy, sz;
int i, l;
MP_DIGITS(&k) = 0;
MP_DIGITS(&qx) = 0;
MP_DIGITS(&qy) = 0;
MP_DIGITS(&qz) = 0;
MP_DIGITS(&sx) = 0;
MP_DIGITS(&sy) = 0;
MP_DIGITS(&sz) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&qx) );
CHECK_MPI_OK( mp_init(&qy) );
CHECK_MPI_OK( mp_init(&qz) );
CHECK_MPI_OK( mp_init(&sx) );
CHECK_MPI_OK( mp_init(&sy) );
CHECK_MPI_OK( mp_init(&sz) );
/* if n = 0 then r = inf */
if (mp_cmp_z(n) == 0) {
mp_zero(rx);
mp_zero(ry);
err = MP_OKAY;
goto cleanup;
/* if n < 0 then out of range error */
} else if (mp_cmp_z(n) < 0) {
err = MP_RANGE;
goto cleanup;
}
/* Q = P, k = n */
CHECK_MPI_OK( mp_copy(px, &qx) );
CHECK_MPI_OK( mp_copy(py, &qy) );
CHECK_MPI_OK( mp_set_int(&qz, 1) );
CHECK_MPI_OK( mp_copy(n, &k) );
/* double and add method */
l = mpl_significant_bits(&k) - 1;
mp_zero(&sx);
mp_zero(&sy);
mp_zero(&sz);
for (i = l; i >= 0; i--) {
/* if k_i = 1, then S = S + Q */
if (MP_GET_BIT(&k, i) != 0) {
CHECK_MPI_OK( GFp_ec_pt_add_jac(p, a, &sx, &sy, &sz,
&qx, &qy, &qz, &sx, &sy, &sz) );
}
if (i > 0) {
/* S = 2S */
CHECK_MPI_OK( GFp_ec_pt_dbl_jac(p, a, &sx, &sy, &sz,
&sx, &sy, &sz) );
}
}
/* convert result S to affine coordinates */
CHECK_MPI_OK( GFp_ec_pt_jac2aff(&sx, &sy, &sz, p, rx, ry) );
cleanup:
mp_clear(&k);
mp_clear(&qx);
mp_clear(&qy);
mp_clear(&qz);
mp_clear(&sx);
mp_clear(&sy);
mp_clear(&sz);
return err;
}
#endif /* NSS_ENABLE_ECC */

Просмотреть файл

@ -0,0 +1,126 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the elliptic curve math library for prime
* field curves.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifndef __gfp_ecl_h_
#define __gfp_ecl_h_
#ifdef NSS_ENABLE_ECC
#include "secmpi.h"
/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
extern mp_err GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py);
/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
extern mp_err GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py);
/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy).
* Uses affine coordinates.
*/
extern mp_err GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = P - Q. Uses affine coordinates. */
extern mp_err GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy,
mp_int *rx, mp_int *ry);
/* Computes R = 2P. Uses affine coordinates. */
extern mp_err GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Uses affine coordinates.
*/
extern mp_err GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a,
const mp_int *b, const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry);
/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
* affine coordinates R(rx, ry).
*/
extern mp_err GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py,
const mp_int *pz, const mp_int *p, mp_int *rx, mp_int *ry);
/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
* coordinates.
*/
extern mp_err GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py,
const mp_int *pz);
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
* coordinates.
*/
extern mp_err GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and
* Q is (qx, qy, qz). Uses Jacobian coordinates.
*/
extern mp_err GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *qx, const mp_int *qy, const mp_int *qz,
mp_int *rx, mp_int *ry, mp_int *rz);
/* Computes R = 2P. Uses Jacobian coordinates. */
extern mp_err GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a,
const mp_int *px, const mp_int *py, const mp_int *pz,
mp_int *rx, mp_int *ry, mp_int *rz);
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
* a, b and p are the elliptic curve coefficients and the prime that
* determines the field GFp. Uses Jacobian coordinates.
*/
mp_err GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b,
const mp_int *px, const mp_int *py, const mp_int *n,
mp_int *rx, mp_int *ry);
#define GFp_ec_pt_is_inf(px, py) GFp_ec_pt_is_inf_aff((px), (py))
#define GFp_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \
GFp_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry))
#define GFp_ECL_JACOBIAN
#ifdef GFp_ECL_AFFINE
#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \
GFp_ec_pt_mul_aff((p), (a), (b), (px), (py), (n), (rx), (ry))
#elif defined(GFp_ECL_JACOBIAN)
#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \
GFp_ec_pt_mul_jac((p), (a), (b), (px), (py), (n), (rx), (ry))
#endif /* GFp_ECL_AFFINE or GFp_ECL_JACOBIAN*/
#endif /* NSS_ENABLE_ECC */
#endif /* __gfp_ecl_h_ */

Просмотреть файл

@ -264,7 +264,7 @@ endif
DEFINES += -DMP_API_COMPATIBLE
MPI_USERS = dh.c pqg.c dsa.c rsa.c
MPI_USERS = dh.c pqg.c dsa.c rsa.c ec.c GFp_ecl.c
MPI_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_SRCS:.c=$(OBJ_SUFFIX)))
MPI_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_USERS:.c=$(OBJ_SUFFIX)))

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: blapi.h,v 1.14 2003-01-30 23:36:35 relyea%netscape.com Exp $
* $Id: blapi.h,v 1.15 2003-02-27 01:31:11 nelsonb%netscape.com Exp $
*/
#ifndef _BLAPI_H_
@ -186,6 +190,70 @@ extern SECStatus KEA_Derive(SECItem *prime,
*/
extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime);
/******************************************************
** Elliptic Curve algorithms
*/
/* Generates a public and private key, both of which are encoded
** in a single ECPrivateKey struct. Params is input, privKey are
** output.
*/
extern SECStatus EC_NewKey(ECParams * params,
ECPrivateKey ** privKey);
extern SECStatus EC_NewKeyFromSeed(ECParams * params,
ECPrivateKey ** privKey,
const unsigned char* seed,
int seedlen);
/* Validates an EC public key as described in Section 5.2.2 of
* X9.63. Such validation prevents against small subgroup attacks
* when the ECDH primitive is used with the cofactor.
*/
extern SECStatus EC_ValidatePublicKey(ECParams * params,
SECItem * publicValue);
/*
** ECDH_Derive performs a scalar point multiplication of a point
** representing a (peer's) public key and a large integer representing
** a private key (its own). Both keys must use the same elliptic curve
** parameters. If the withCofactor parameter is true, the
** multiplication also uses the cofactor associated with the curve
** parameters. The output of this scheme is the x-coordinate of the
** resulting point. If successful, derivedSecret->data is set to the
** address of the newly allocated buffer containing the derived
** secret, and derivedSecret->len is the size of the secret
** produced. It is the caller's responsibility to free the allocated
** buffer containing the derived secret.
*/
extern SECStatus ECDH_Derive(SECItem * publicValue,
ECParams * params,
SECItem * privateValue,
PRBool withCofactor,
SECItem * derivedSecret);
/* On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
extern SECStatus ECDSA_SignDigest(ECPrivateKey *key,
SECItem *signature,
const SECItem *digest);
/* On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
*/
extern SECStatus ECDSA_VerifyDigest(ECPublicKey *key,
const SECItem *signature,
const SECItem *digest);
/* Uses the provided seed. */
extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *key,
SECItem *signature,
const SECItem *digest,
const unsigned char *seed,
const int seedlen);
/******************************************/
/*

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: blapit.h,v 1.8 2003-01-30 23:36:36 relyea%netscape.com Exp $
* $Id: blapit.h,v 1.9 2003-02-27 01:31:12 nelsonb%netscape.com Exp $
*/
#ifndef _BLAPIT_H_
@ -66,6 +70,14 @@
#define DSA_SIGNATURE_LEN 40 /* Bytes */
#define DSA_SUBPRIME_LEN 20 /* Bytes */
/* XXX We shouldn't have to hard code this limit. For
* now, this is the quickest way to support ECDSA signature
* processing (ECDSA signature lengths depend on curve
* size). This limit is sufficient for curves upto
* 576 bits.
*/
#define MAX_ECKEY_LEN 72 /* Bytes */
/*
* Number of bytes each hash algorithm produces
*/
@ -252,5 +264,73 @@ struct DHPrivateKeyStr {
};
typedef struct DHPrivateKeyStr DHPrivateKey;
/***************************************************************************
** Data structures used for elliptic curve parameters and
** public and private keys.
*/
/*
** The ECParams data structures can encode elliptic curve
** parameters for both GFp and GF2m curves.
*/
typedef enum { ec_params_explicit,
ec_params_named
} ECParamsType;
typedef enum { ec_field_GFp = 1,
ec_field_GF2m
} ECFieldType;
struct ECFieldIDStr {
int size; /* field size in bits */
ECFieldType type;
union {
SECItem prime; /* prime p for (GFp) */
SECItem m; /* integer m for (GF2m) */
} u;
int k1; /* first coefficient of pentanomial or
* the only coefficient of trinomial
*/
int k2; /* two remaining coefficients of pentanomial */
int k3;
};
typedef struct ECFieldIDStr ECFieldID;
struct ECCurveStr {
SECItem a; /* contains octet stream encoding of
* field element (X9.62 section 4.3.3)
*/
SECItem b;
SECItem seed;
};
typedef struct ECCurveStr ECCurve;
struct ECParamsStr {
PRArenaPool * arena;
ECParamsType type;
ECFieldID fieldID;
ECCurve curve;
SECItem base;
SECItem order;
int cofactor;
SECItem DEREncoding;
};
typedef struct ECParamsStr ECParams;
struct ECPublicKeyStr {
ECParams ecParams;
SECItem publicValue; /* elliptic curve point encoded as
* octet stream.
*/
};
typedef struct ECPublicKeyStr ECPublicKey;
struct ECPrivateKeyStr {
ECParams ecParams;
SECItem publicValue; /* encoded ec point */
SECItem privateValue; /* private big integer */
};
typedef struct ECPrivateKeyStr ECPrivateKey;
#endif /* _BLAPIT_H_ */

Просмотреть файл

@ -0,0 +1,958 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Elliptic Curve Cryptography library.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#include "blapi.h"
#include "prerr.h"
#include "secerr.h"
#include "secmpi.h"
#include "secitem.h"
#include "ec.h"
#include "GFp_ecl.h"
#ifdef NSS_ENABLE_ECC
/*
* Returns true if pointP is the point at infinity, false otherwise
*/
PRBool
ec_point_at_infinity(SECItem *pointP)
{
int i;
for (i = 1; i < pointP->len; i++) {
if (pointP->data[i] != 0x00) return PR_FALSE;
}
return PR_TRUE;
}
/*
* Computes point addition R = P + Q for the curve whose
* parameters are encoded in params. Two or more of P, Q,
* R may point to the same memory location.
*/
SECStatus
ec_point_add(ECParams *params, SECItem *pointP,
SECItem *pointQ, SECItem *pointR)
{
mp_int Px, Py, Qx, Qy, Rx, Ry;
mp_int prime, a;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
int i;
printf("ec_point_add: params [len=%d]:", params->DEREncoding.len);
for (i = 0; i < params->DEREncoding.len; i++)
printf("%02x:", params->DEREncoding.data[i]);
printf("\n");
printf("ec_point_add: pointP [len=%d]:", pointP->len);
for (i = 0; i < pointP->len; i++)
printf("%02x:", pointP->data[i]);
printf("\n");
printf("ec_point_add: pointQ [len=%d]:", pointQ->len);
for (i = 0; i < pointQ->len; i++)
printf("%02x:", pointQ->data[i]);
printf("\n");
#endif
/* NOTE: We only support prime field curves for now */
len = (params->fieldID.size + 7) >> 3;
if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointP->len != (2 * len + 1)) ||
(pointQ->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointQ->len != (2 * len + 1))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&Px) = 0;
MP_DIGITS(&Py) = 0;
MP_DIGITS(&Qx) = 0;
MP_DIGITS(&Qy) = 0;
MP_DIGITS(&Rx) = 0;
MP_DIGITS(&Ry) = 0;
MP_DIGITS(&prime) = 0;
MP_DIGITS(&a) = 0;
CHECK_MPI_OK( mp_init(&Px) );
CHECK_MPI_OK( mp_init(&Py) );
CHECK_MPI_OK( mp_init(&Qx) );
CHECK_MPI_OK( mp_init(&Qy) );
CHECK_MPI_OK( mp_init(&Rx) );
CHECK_MPI_OK( mp_init(&Ry) );
CHECK_MPI_OK( mp_init(&prime) );
CHECK_MPI_OK( mp_init(&a) );
/* Initialize Px and Py */
CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len,
(mp_size) len) );
/* Initialize Qx and Qy */
CHECK_MPI_OK( mp_read_unsigned_octets(&Qx, pointQ->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Qy, pointQ->data + 1 + len,
(mp_size) len) );
/* Set up the prime and curve coefficient */
SECITEM_TO_MPINT( params->fieldID.u.prime, &prime );
SECITEM_TO_MPINT( params->curve.a, &a );
/* Compute R = P + Q */
if (GFp_ec_pt_add(&prime, &a, &Px, &Py, &Qx, &Qy,
&Rx, &Ry) != SECSuccess)
goto cleanup;
/* Construct the SECItem representation of the result */
pointR->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK( mp_to_fixlen_octets(&Rx, pointR->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&Ry, pointR->data + 1 + len,
(mp_size) len) );
rv = SECSuccess;
#if EC_DEBUG
printf("ec_point_add: pointR [len=%d]:", pointR->len);
for (i = 0; i < pointR->len; i++)
printf("%02x:", pointR->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&Px);
mp_clear(&Py);
mp_clear(&Qx);
mp_clear(&Qy);
mp_clear(&Rx);
mp_clear(&Ry);
mp_clear(&prime);
mp_clear(&a);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
/*
* Computes scalar point multiplication pointQ = k * pointP for
* the curve whose parameters are encoded in params.
*/
SECStatus
ec_point_mul(ECParams *params, mp_int *k,
SECItem *pointP, SECItem *pointQ)
{
mp_int Px, Py, Qx, Qy;
mp_int prime, a, b;
SECStatus rv = SECFailure;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
int i;
char mpstr[256];
printf("ec_point_mul: params [len=%d]:", params->DEREncoding.len);
for (i = 0; i < params->DEREncoding.len; i++)
printf("%02x:", params->DEREncoding.data[i]);
printf("\n");
mp_tohex(k, mpstr);
printf("ec_point_mul: scalar : %s\n", mpstr);
mp_todecimal(k, mpstr);
printf("ec_point_mul: scalar : %s (dec)\n", mpstr);
printf("ec_point_mul: pointP [len=%d]:", pointP->len);
for (i = 0; i < pointP->len; i++)
printf("%02x:", pointP->data[i]);
printf("\n");
#endif
/* NOTE: We only support prime field curves for now */
len = (params->fieldID.size + 7) >> 3;
if ((params->fieldID.type != ec_field_GFp) ||
(pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
(pointP->len != (2 * len + 1))) {
return SECFailure;
};
MP_DIGITS(&Px) = 0;
MP_DIGITS(&Py) = 0;
MP_DIGITS(&Qx) = 0;
MP_DIGITS(&Qy) = 0;
MP_DIGITS(&prime) = 0;
MP_DIGITS(&a) = 0;
MP_DIGITS(&b) = 0;
CHECK_MPI_OK( mp_init(&Px) );
CHECK_MPI_OK( mp_init(&Py) );
CHECK_MPI_OK( mp_init(&Qx) );
CHECK_MPI_OK( mp_init(&Qy) );
CHECK_MPI_OK( mp_init(&prime) );
CHECK_MPI_OK( mp_init(&a) );
CHECK_MPI_OK( mp_init(&b) );
/* Initialize Px and Py */
CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len,
(mp_size) len) );
/* Set up mp_ints containing the prime and curve coefficients */
SECITEM_TO_MPINT( params->fieldID.u.prime, &prime );
SECITEM_TO_MPINT( params->curve.a, &a );
SECITEM_TO_MPINT( params->curve.b, &b );
/* Compute Q = k * P */
if (GFp_ec_pt_mul(&prime, &a, &b, &Px, &Py, k,
&Qx, &Qy) != SECSuccess)
goto cleanup;
/* Construct the SECItem representation of point Q */
pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
(mp_size) len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
(mp_size) len) );
rv = SECSuccess;
#if EC_DEBUG
printf("ec_point_mul: pointQ [len=%d]:", pointQ->len);
for (i = 0; i < pointQ->len; i++)
printf("%02x:", pointQ->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&Px);
mp_clear(&Py);
mp_clear(&Qx);
mp_clear(&Qy);
mp_clear(&prime);
mp_clear(&a);
mp_clear(&b);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
static unsigned char bitmask[] = {
0xff, 0x7f, 0x3f, 0x1f,
0x0f, 0x07, 0x03, 0x01
};
#endif /* NSS_ENABLE_ECC */
/* Generates a new EC key pair. The private key is a supplied
* random value (in seed) and the public key is the result of
* performing a scalar point multiplication of that value with
* the curve's base point.
*/
SECStatus
EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
const unsigned char *seed, int seedlen)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
PRArenaPool *arena;
ECPrivateKey *key;
mp_int k;
mp_err err = MP_OKAY;
int len;
#if EC_DEBUG
printf("EC_NewKeyFromSeed called\n");
#endif
if (!ecParams || !privKey || !seed || (seedlen < 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize an arena for the EC key. */
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
return SECFailure;
key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
if (!key) {
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
/* Copy all of the fields from the ECParams argument to the
* ECParams structure within the private key.
*/
key->ecParams.arena = arena;
key->ecParams.type = ecParams->type;
key->ecParams.fieldID.size = ecParams->fieldID.size;
key->ecParams.fieldID.type = ecParams->fieldID.type;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
&ecParams->fieldID.u.prime));
key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
&ecParams->curve.a));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
&ecParams->curve.b));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
&ecParams->curve.seed));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
&ecParams->base));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
&ecParams->order));
key->ecParams.cofactor = ecParams->cofactor;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
&ecParams->DEREncoding));
len = (ecParams->fieldID.size + 7) >> 3;
SECITEM_AllocItem(arena, &key->privateValue, len);
SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1);
/* Copy private key */
if (seedlen >= len) {
memcpy(key->privateValue.data, seed, len);
} else {
memset(key->privateValue.data, 0, (len - seedlen));
memcpy(key->privateValue.data + (len - seedlen), seed, seedlen);
}
/* Compute corresponding public key */
MP_DIGITS(&k) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
(mp_size) len) );
rv = ec_point_mul(ecParams, &k, &(ecParams->base), &(key->publicValue));
if (rv != SECSuccess) goto cleanup;
*privKey = key;
cleanup:
mp_clear(&k);
if (rv)
PORT_FreeArena(arena, PR_TRUE);
#if EC_DEBUG
printf("EC_NewKeyFromSeed returning %s\n",
(rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Generates a new EC key pair. The private key is a random value and
* the public key is the result of performing a scalar point multiplication
* of that value with the curve's base point.
*/
SECStatus
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
int len;
unsigned char *seed;
if (!ecParams || !privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Generate random private key */
len = (ecParams->fieldID.size + 7) >> 3;
if ((seed = PORT_Alloc(len)) == NULL) goto cleanup;
if (RNG_GenerateGlobalRandomBytes(seed, len) != SECSuccess) goto cleanup;
/* Fit private key to the field size */
seed[0] &= bitmask[len * 8 - ecParams->fieldID.size];
rv = EC_NewKeyFromSeed(ecParams, privKey, seed, len);
cleanup:
if (!seed) {
PORT_ZFree(seed, len);
}
#if EC_DEBUG
printf("EC_NewKey returning %s\n",
(rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Validates an EC public key as described in Section 5.2.2 of
* X9.63. The ECDH primitive when used without the cofactor does
* not address small subgroup attacks, which may occur when the
* public key is not valid. These attacks can be prevented by
* validating the public key before using ECDH.
*/
SECStatus
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
{
#ifdef NSS_ENABLE_ECC
if (!ecParams || !publicValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* XXX Add actual checks here. */
return SECSuccess;
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
return SECFailure;
#endif /* NSS_ENABLE_ECC */
}
/*
** Performs an ECDH key derivation by computing the scalar point
** multiplication of privateValue and publicValue (with or without the
** cofactor) and returns the x-coordinate of the resulting elliptic
** curve point in derived secret. If successful, derivedSecret->data
** is set to the address of the newly allocated buffer containing the
** derived secret, and derivedSecret->len is the size of the secret
** produced. It is the caller's responsibility to free the allocated
** buffer containing the derived secret.
*/
SECStatus
ECDH_Derive(SECItem *publicValue,
ECParams *ecParams,
SECItem *privateValue,
PRBool withCofactor,
SECItem *derivedSecret)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
unsigned int len = 0;
SECItem pointQ = {siBuffer, NULL, 0};
mp_int k; /* to hold the private value */
mp_int cofactor;
mp_err err = MP_OKAY;
#if EC_DEBUG
int i;
#endif
if (!publicValue || !ecParams || !privateValue ||
!derivedSecret) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
len = (ecParams->fieldID.size + 7) >> 3;
pointQ.len = 2*len + 1;
if ((pointQ.data = PORT_Alloc(2*len + 1)) == NULL) goto cleanup;
MP_DIGITS(&k) = 0;
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
(mp_size) privateValue->len) );
if (withCofactor && (ecParams->cofactor != 1)) {
/* multiply k with the cofactor */
MP_DIGITS(&cofactor) = 0;
CHECK_MPI_OK( mp_init(&cofactor) );
mp_set(&cofactor, ecParams->cofactor);
CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
}
/* Multiply our private key and peer's public point */
if ((ec_point_mul(ecParams, &k, publicValue, &pointQ) != SECSuccess) ||
ec_point_at_infinity(&pointQ))
goto cleanup;
/* Allocate memory for the derived secret and copy
* the x co-ordinate of pointQ into it.
*/
SECITEM_AllocItem(NULL, derivedSecret, len);
memcpy(derivedSecret->data, pointQ.data + 1, len);
rv = SECSuccess;
#if EC_DEBUG
printf("derived_secret:\n");
for (i = 0; i < derivedSecret->len; i++)
printf("%02x:", derivedSecret->data[i]);
printf("\n");
#endif
cleanup:
mp_clear(&k);
if (pointQ.data) {
PORT_ZFree(pointQ.data, 2*len + 1);
}
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/* Computes the ECDSA signature (a concatenation of two values r and s)
* on the digest using the given key and the random value kb (used in
* computing s).
*/
SECStatus
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
const SECItem *digest, const unsigned char *kb, const int kblen)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
mp_int x1;
mp_int d, k; /* private key, random integer */
mp_int r, s; /* tuple (r, s) is the signature */
mp_int n;
mp_err err = MP_OKAY;
ECParams *ecParams = NULL;
SECItem kGpoint = { siBuffer, NULL, 0};
int len = 0;
#if EC_DEBUG
char mpstr[256];
#endif
/* Check args */
if (!key || !signature || !digest || !kb || (kblen < 0) ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
ecParams = &(key->ecParams);
len = (ecParams->fieldID.size + 7) >> 3;
if (signature->len < 2*len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
/* Initialize MPI integers. */
MP_DIGITS(&x1) = 0;
MP_DIGITS(&d) = 0;
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
MP_DIGITS(&n) = 0;
CHECK_MPI_OK( mp_init(&x1) );
CHECK_MPI_OK( mp_init(&d) );
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&r) );
CHECK_MPI_OK( mp_init(&s) );
CHECK_MPI_OK( mp_init(&n) );
SECITEM_TO_MPINT( ecParams->order, &n );
SECITEM_TO_MPINT( key->privateValue, &d );
CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
/* Make sure k is in the interval [1, n-1] */
if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
** ANSI X9.62, Section 5.3.2, Step 2
**
** Compute kG
*/
kGpoint.len = 2*len + 1;
kGpoint.data = PORT_Alloc(2*len + 1);
if ((kGpoint.data == NULL) ||
(ec_point_mul(ecParams, &k, &(ecParams->base), &kGpoint)
!= SECSuccess))
goto cleanup;
/*
** ANSI X9.62, Section 5.3.3, Step 1
**
** Extract the x co-ordinate of kG into x1
*/
CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
(mp_size) len) );
/*
** ANSI X9.62, Section 5.3.3, Step 2
**
** r = x1 mod n NOTE: n is the order of the curve
*/
CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
/*
** ANSI X9.62, Section 5.3.3, Step 3
**
** verify r != 0
*/
if (mp_cmp_z(&r) == 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
** ANSI X9.62, Section 5.3.3, Step 4
**
** s = (k**-1 * (SHA1(M) + d*r)) mod n
*/
SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */
#if EC_DEBUG
mp_todecimal(&n, mpstr);
printf("n : %s (dec)\n", mpstr);
mp_todecimal(&d, mpstr);
printf("d : %s (dec)\n", mpstr);
mp_tohex(&x1, mpstr);
printf("x1: %s\n", mpstr);
mp_todecimal(&s, mpstr);
printf("digest: %s (decimal)\n", mpstr);
mp_todecimal(&r, mpstr);
printf("r : %s (dec)\n", mpstr);
#endif
CHECK_MPI_OK( mp_invmod(&k, &n, &k) ); /* k = k**-1 mod n */
CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) ); /* d = d * r mod n */
CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) ); /* s = s + d mod n */
CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) ); /* s = s * k mod n */
#if EC_DEBUG
mp_todecimal(&s, mpstr);
printf("s : %s (dec)\n", mpstr);
#endif
/*
** ANSI X9.62, Section 5.3.3, Step 5
**
** verify s != 0
*/
if (mp_cmp_z(&s) == 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
goto cleanup;
}
/*
**
** Signature is tuple (r, s)
*/
CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, len) );
CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + len, len) );
signature->len = 2*len;
rv = SECSuccess;
err = MP_OKAY;
cleanup:
mp_clear(&x1);
mp_clear(&d);
mp_clear(&k);
mp_clear(&r);
mp_clear(&s);
mp_clear(&n);
if (kGpoint.data) {
PORT_ZFree(kGpoint.data, 2*len + 1);
}
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA signing with seed %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/*
** Computes the ECDSA signature on the digest using the given key
** and a random seed.
*/
SECStatus
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
int prerr = 0;
int n = (key->ecParams.fieldID.size + 7) >> 3;
unsigned char mask = bitmask[n * 8 - key->ecParams.fieldID.size];
unsigned char *kseed = NULL;
/* Generate random seed of appropriate size as dictated
* by field size.
*/
if ((kseed = PORT_Alloc(n)) == NULL) return SECFailure;
do {
if (RNG_GenerateGlobalRandomBytes(kseed, n) != SECSuccess)
goto cleanup;
*kseed &= mask;
rv = ECDSA_SignDigestWithSeed(key, signature, digest, kseed, n);
if (rv) prerr = PORT_GetError();
} while ((rv != SECSuccess) && (prerr == SEC_ERROR_NEED_RANDOM));
cleanup:
if (kseed) PORT_ZFree(kseed, n);
#if EC_DEBUG
printf("ECDSA signing %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}
/*
** Checks the signature on the given digest using the key provided.
*/
SECStatus
ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
mp_int r_, s_; /* tuple (r', s') is received signature) */
mp_int c, u1, u2, v; /* intermediate values used in verification */
mp_int x1, y1;
mp_int x2, y2;
mp_int n;
mp_err err = MP_OKAY;
PRArenaPool *arena = NULL;
ECParams *ecParams = NULL;
SECItem pointA = { siBuffer, NULL, 0 };
SECItem pointB = { siBuffer, NULL, 0 };
SECItem pointC = { siBuffer, NULL, 0 };
int len;
#if EC_DEBUG
char mpstr[256];
printf("ECDSA verification called\n");
#endif
/* Check args */
if (!key || !signature || !digest ||
(digest->len != SHA1_LENGTH)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
ecParams = &(key->ecParams);
len = (ecParams->fieldID.size + 7) >> 3;
printf("len is %d\n", len);
if (signature->len < 2*len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
/* Initialize an arena for pointA, pointB and pointC */
if ((arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)) == NULL)
goto cleanup;
SECITEM_AllocItem(arena, &pointA, 2*len + 1);
SECITEM_AllocItem(arena, &pointB, 2*len + 1);
SECITEM_AllocItem(arena, &pointC, 2*len + 1);
if (pointA.data == NULL || pointB.data == NULL || pointC.data == NULL)
goto cleanup;
/* Initialize MPI integers. */
MP_DIGITS(&r_) = 0;
MP_DIGITS(&s_) = 0;
MP_DIGITS(&c) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&x1) = 0;
MP_DIGITS(&y1) = 0;
MP_DIGITS(&x2) = 0;
MP_DIGITS(&y2) = 0;
MP_DIGITS(&v) = 0;
MP_DIGITS(&n) = 0;
CHECK_MPI_OK( mp_init(&r_) );
CHECK_MPI_OK( mp_init(&s_) );
CHECK_MPI_OK( mp_init(&c) );
CHECK_MPI_OK( mp_init(&u1) );
CHECK_MPI_OK( mp_init(&u2) );
CHECK_MPI_OK( mp_init(&x1) );
CHECK_MPI_OK( mp_init(&y1) );
CHECK_MPI_OK( mp_init(&x2) );
CHECK_MPI_OK( mp_init(&y2) );
CHECK_MPI_OK( mp_init(&v) );
CHECK_MPI_OK( mp_init(&n) );
/*
** Convert received signature (r', s') into MPI integers.
*/
CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, len) );
CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + len, len) );
/*
** ANSI X9.62, Section 5.4.2, Steps 1 and 2
**
** Verify that 0 < r' < n and 0 < s' < n
*/
SECITEM_TO_MPINT(ecParams->order, &n);
if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0)
goto cleanup; /* will return rv == SECFailure */
/*
** ANSI X9.62, Section 5.4.2, Step 3
**
** c = (s')**-1 mod n
*/
CHECK_MPI_OK( mp_invmod(&s_, &n, &c) ); /* c = (s')**-1 mod n */
/*
** ANSI X9.62, Section 5.4.2, Step 4
**
** u1 = ((SHA1(M')) * c) mod n
*/
SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
#if EC_DEBUG
mp_todecimal(&r_, mpstr);
printf("r_: %s (dec)\n", mpstr);
mp_todecimal(&s_, mpstr);
printf("s_: %s (dec)\n", mpstr);
mp_todecimal(&c, mpstr);
printf("c : %s (dec)\n", mpstr);
mp_todecimal(&u1, mpstr);
printf("digest: %s (dec)\n", mpstr);
#endif
CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) ); /* u1 = u1 * c mod n */
/*
** ANSI X9.62, Section 5.4.2, Step 4
**
** u2 = ((r') * c) mod n
*/
CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
/*
** ANSI X9.62, Section 5.4.3, Step 1
**
** Compute u1*G + u2*Q
** Here, A = u1.G B = u2.Q and C = A + B
** If the result, C, is the point at infinity, reject the signature
*/
if ((ec_point_mul(ecParams, &u1, &ecParams->base, &pointA)
== SECFailure) ||
(ec_point_mul(ecParams, &u2, &key->publicValue, &pointB)
== SECFailure) ||
(ec_point_add(ecParams, &pointA, &pointB, &pointC) == SECFailure) ||
ec_point_at_infinity(&pointC)) {
rv = SECFailure;
goto cleanup;
}
CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, len) );
/*
** ANSI X9.62, Section 5.4.4, Step 2
**
** v = x1 mod n
*/
CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
/*
** ANSI X9.62, Section 5.4.4, Step 3
**
** Verification: v == r'
*/
if (mp_cmp(&v, &r_)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure; /* Signature failed to verify. */
} else {
rv = SECSuccess; /* Signature verified. */
}
#if EC_DEBUG
mp_todecimal(&u1, mpstr);
printf("u1: %s (dec)\n", mpstr);
mp_todecimal(&u2, mpstr);
printf("u2: %s (dec)\n", mpstr);
mp_tohex(&x1, mpstr);
printf("x1: %s\n", mpstr);
mp_todecimal(&v, mpstr);
printf("v : %s (dec)\n", mpstr);
#endif
cleanup:
mp_clear(&r_);
mp_clear(&s_);
mp_clear(&c);
mp_clear(&u1);
mp_clear(&u2);
mp_clear(&x1);
mp_clear(&y1);
mp_clear(&x2);
mp_clear(&y2);
mp_clear(&v);
mp_clear(&n);
if (arena) PORT_FreeArena(arena, PR_TRUE);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA verification %s\n",
(rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_ENABLE_ECC */
return rv;
}

Просмотреть файл

@ -0,0 +1,50 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Elliptic Curve Cryptography library.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifndef __ec_h_
#define __ec_h_
#define EC_DEBUG 0
#define EC_POINT_FORM_COMPRESSED_Y0 0x02
#define EC_POINT_FORM_COMPRESSED_Y1 0x03
#define EC_POINT_FORM_UNCOMPRESSED 0x04
#define EC_POINT_FORM_HYBRID_Y0 0x06
#define EC_POINT_FORM_HYBRID_Y1 0x07
#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
#define SECG_CURVE_OID_TOTAL_LEN 7
#endif /* __ec_h_ */

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: ldvector.c,v 1.5 2003-01-30 23:36:36 relyea%netscape.com Exp $
* $Id: ldvector.c,v 1.6 2003-02-27 01:31:13 nelsonb%netscape.com Exp $
*/
#include "loader.h"
@ -171,6 +175,16 @@ static const struct FREEBLVectorStr vector = {
BLAPI_VerifySelf,
/* End of Version 3.005. */
EC_NewKey,
EC_NewKeyFromSeed,
EC_ValidatePublicKey,
ECDH_Derive,
ECDSA_SignDigest,
ECDSA_VerifyDigest,
ECDSA_SignDigestWithSeed,
/* End of Version 3.006. */
};

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: loader.c,v 1.13 2003-01-30 23:36:36 relyea%netscape.com Exp $
* $Id: loader.c,v 1.14 2003-02-27 01:31:14 nelsonb%netscape.com Exp $
*/
#include "loader.h"
@ -1294,3 +1298,69 @@ BLAPI_VerifySelf(const char *name)
return PR_FALSE;
return vector->p_BLAPI_VerifySelf(libraryName);
}
/* ============== New for 3.006 =============================== */
SECStatus
EC_NewKey(ECParams * params, ECPrivateKey ** privKey)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_EC_NewKey)( params, privKey );
}
SECStatus
EC_NewKeyFromSeed(ECParams * params, ECPrivateKey ** privKey,
const unsigned char *seed, int seedlen)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_EC_NewKeyFromSeed)( params, privKey, seed, seedlen );
}
SECStatus
EC_ValidatePublicKey(ECParams * params, SECItem * publicValue)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_EC_ValidatePublicKey)( params, publicValue );
}
SECStatus
ECDH_Derive(SECItem * publicValue, ECParams * params, SECItem * privateValue,
PRBool withCofactor, SECItem * derivedSecret)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_ECDH_Derive)( publicValue, params, privateValue,
withCofactor, derivedSecret );
}
SECStatus
ECDSA_SignDigest(ECPrivateKey * key, SECItem * signature,
const SECItem * digest)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_ECDSA_SignDigest)( key, signature, digest );
}
SECStatus
ECDSA_VerifyDigest(ECPublicKey * key, const SECItem * signature,
const SECItem * digest)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_ECDSA_VerifyDigest)( key, signature, digest );
}
SECStatus
ECDSA_SignDigestWithSeed(ECPrivateKey * key, SECItem * signature,
const SECItem * digest, const unsigned char *seed, const int seedlen)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_ECDSA_SignDigestWithSeed)( key, signature, digest,
seed, seedlen );
}

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: loader.h,v 1.8 2003-01-30 23:36:37 relyea%netscape.com Exp $
* $Id: loader.h,v 1.9 2003-02-27 01:31:14 nelsonb%netscape.com Exp $
*/
#ifndef _LOADER_H_
@ -40,7 +44,7 @@
#include "blapi.h"
#define FREEBL_VERSION 0x0305
#define FREEBL_VERSION 0x0306
struct FREEBLVectorStr {
@ -333,6 +337,40 @@ struct FREEBLVectorStr {
PRBool (*p_BLAPI_VerifySelf)(const char *name);
/* Version 3.005 came to here */
SECStatus (* p_EC_NewKey)(ECParams * params,
ECPrivateKey ** privKey);
SECStatus (* p_EC_NewKeyFromSeed)(ECParams * params,
ECPrivateKey ** privKey,
const unsigned char * seed,
int seedlen);
SECStatus (* p_EC_ValidatePublicKey)(ECParams * params,
SECItem * publicValue);
SECStatus (* p_ECDH_Derive)(SECItem * publicValue,
ECParams * params,
SECItem * privateValue,
PRBool withCofactor,
SECItem * derivedSecret);
SECStatus (* p_ECDSA_SignDigest)(ECPrivateKey * key,
SECItem * signature,
const SECItem * digest);
SECStatus (* p_ECDSA_VerifyDigest)(ECPublicKey * key,
const SECItem * signature,
const SECItem * digest);
SECStatus (* p_ECDSA_SignDigestWithSeed)(ECPrivateKey * key,
SECItem * signature,
const SECItem * digest,
const unsigned char * seed,
const int seedlen);
/* Version 3.006 came to here */
};
typedef struct FREEBLVectorStr FREEBLVector;

Просмотреть файл

@ -16,7 +16,11 @@
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
# Sun Microsystems, Inc. All Rights Reserved.
#
# Contributor(s):
# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
@ -61,6 +65,7 @@ EXPORTS = \
PRIVATE_EXPORTS = \
secmpi.h \
ec.h \
$(NULL)
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h
@ -93,6 +98,8 @@ CSRCS = \
rijndael.c \
aeskeywrap.c \
dh.c \
ec.c \
GFp_ecl.c \
pqg.c \
dsa.c \
rsa.c \
@ -107,6 +114,8 @@ ALL_HDRS = \
blapi.h \
blapit.h \
des.h \
ec.h \
GFp_ecl.h \
loader.h \
rijndael.h \
secmpi.h \

Просмотреть файл

@ -16,8 +16,12 @@
;+# Copyright (C) 2000 Netscape Communications Corporation. All
;+# Rights Reserved.
;+#
;+# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
;+# Sun Microsystems, Inc. All Rights Reserved.
;+#
;+# Contributor(s):
;+# Dr Stephen Henson <stephen.henson@gemplus.com>
;+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
;+#
;+# Alternatively, the contents of this file may be used under the
;+# terms of the GNU General Public License Version 2 or later (the
@ -746,6 +750,8 @@ PK11_UpdateSlotAttribute;
PK11_UserEnableSlot;
PK11_UserDisableSlot;
SECITEM_ItemsAreEqual;
SECKEY_CreateECPrivateKey;
SECKEY_PublicKeyStrengthInBits;
;+ local:
;+ *;
;+};

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -50,6 +54,7 @@
#include "cert.h"
#include "secerr.h"
#include "secpkcs5.h"
#include "ec.h"
#define PAIRWISE_SECITEM_TYPE siBuffer
#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
@ -572,7 +577,19 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data,
pubKey->u.dh.publicValue.len); attrs++;
break;
/* what about fortezza??? */
#ifdef NSS_ENABLE_ECC
case ecKey:
keyType = CKK_EC;
PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
signedattr = attrs;
PK11_SETATTRS(attrs, CKA_EC_PARAMS,
pubKey->u.ec.DEREncodedParams.data,
pubKey->u.ec.DEREncodedParams.len); attrs++;
PK11_SETATTRS(attrs, CKA_EC_POINT, pubKey->u.ec.publicValue.data,
pubKey->u.ec.publicValue.len); attrs++;
break;
#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return CK_INVALID_HANDLE;
@ -767,6 +784,9 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
CK_ATTRIBUTE template[8];
CK_ATTRIBUTE *attrs= template;
CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;
#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE *ecparams;
#endif /* NSS_ENABLE_ECC */
/* if we didn't know the key type, get it */
if (keyType== nullKey) {
@ -785,6 +805,11 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
case CKK_DH:
keyType = dhKey;
break;
#ifdef NSS_ENABLE_ECC
case CKK_EC:
keyType = ecKey;
break;
#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return NULL;
@ -889,6 +914,30 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);
if (crv != CKR_OK) break;
break;
#ifdef NSS_ENABLE_ECC
case ecKey:
pubKey->u.ec.size = 0;
ecparams = attrs;
PK11_SETATTRS(attrs, CKA_EC_PARAMS, NULL, 0); attrs++;
value =attrs;
PK11_SETATTRS(attrs, CKA_EC_POINT, NULL, 0); attrs++;
templateCount = attrs - template;
PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
if (crv != CKR_OK) break;
if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC)) {
crv = CKR_OBJECT_HANDLE_INVALID;
break;
}
crv = pk11_Attr2SecItem(arena,ecparams,
&pubKey->u.ec.DEREncodedParams);
if (crv != CKR_OK) break;
crv = pk11_Attr2SecItem(arena,value,&pubKey->u.ec.publicValue);
if (crv != CKR_OK) break;
break;
#endif /* NSS_ENABLE_ECC */
case fortezzaKey:
case nullKey:
default:
@ -929,6 +978,9 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
case CKK_DSA: keyType = dsaKey; break;
case CKK_DH: keyType = dhKey; break;
case CKK_KEA: keyType = fortezzaKey; break;
#ifdef NSS_ENABLE_ECC
case CKK_EC: keyType = ecKey; break;
#endif /* NSS_ENABLE_ECC */
default:
break;
}
@ -1088,6 +1140,10 @@ pk11_mapSignKeyType(KeyType keyType)
case fortezzaKey:
case dsaKey:
return CKM_DSA;
#ifdef NSS_ENABLE_ECC
case ecKey:
return CKM_ECDSA;
#endif /* NSS_ENABLE_ECC */
case dhKey:
default:
break;
@ -1660,6 +1716,7 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
/*
* We are not doing consistency check for Diffie-Hellman Key -
* otherwise it would be here
* This is also true for Elliptic Curve Diffie-Hellman keys
*/
}
@ -1876,6 +1933,19 @@ PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
{ CKA_VERIFY_RECOVER, NULL, 0},
{ CKA_ENCRYPT, NULL, 0},
};
#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE ecPubTemplate[] = {
{ CKA_EC_PARAMS, NULL, 0 },
{ CKA_TOKEN, NULL, 0},
{ CKA_DERIVE, NULL, 0},
{ CKA_WRAP, NULL, 0},
{ CKA_VERIFY, NULL, 0},
{ CKA_VERIFY_RECOVER, NULL, 0},
{ CKA_ENCRYPT, NULL, 0},
};
int ecPubCount = sizeof(ecPubTemplate)/sizeof(ecPubTemplate[0]);
SECKEYECParams * ecParams;
#endif /* NSS_ENABLE_ECC */
int dsaPubCount = sizeof(dsaPubTemplate)/sizeof(dsaPubTemplate[0]);
/*CK_ULONG key_size = 0;*/
@ -2019,6 +2089,23 @@ PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
keyType = dhKey;
test_mech.mechanism = CKM_DH_PKCS_DERIVE;
break;
#ifdef NSS_ENABLE_ECC
case CKM_EC_KEY_PAIR_GEN:
ecParams = (SECKEYECParams *)param;
attrs = ecPubTemplate;
PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
ecParams->len); attrs++;
pubTemplate = ecPubTemplate;
pubCount = ecPubCount;
keyType = ecKey;
/* XXX An EC key can be used for other mechanisms too such
* as CKM_ECDSA and CKM_ECDSA_SHA1. How can we reflect
* that in test_mech.mechanism so the CKA_SIGN, CKA_VERIFY
* attributes are set correctly?
*/
test_mech.mechanism = CKM_ECDH1_DERIVE;
break;
#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return NULL;
@ -2042,6 +2129,15 @@ PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
case CKM_DH_PKCS_DERIVE:
mechanism_info.flags = CKF_DERIVE;
break;
#ifdef NSS_ENABLE_ECC
case CKM_ECDH1_DERIVE:
mechanism_info.flags = CKF_DERIVE;
break;
case CKM_ECDSA:
case CKM_ECDSA_SHA1:
mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
break;
#endif /* NSS_ENABLE_ECC */
default:
break;
}
@ -2137,6 +2233,11 @@ PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
case CKM_DH_PKCS_KEY_PAIR_GEN:
pubKeyIndex = &(*pubKey)->u.dh.publicValue;
break;
#ifdef NSS_ENABLE_ECC
case CKM_EC_KEY_PAIR_GEN:
pubKeyIndex = &(*pubKey)->u.ec.publicValue;
break;
#endif /* NSS_ENABLE_ECC */
}
PORT_Assert(pubKeyIndex != NULL);
@ -2695,6 +2796,62 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
PORT_SetError( PK11_MapError(crv) );
}
break;
#ifdef NSS_ENABLE_ECC
case ecKey:
{
CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
CK_ULONG key_size = 0;
CK_ATTRIBUTE keyTemplate[4];
int templateCount;
CK_ATTRIBUTE *attrs = keyTemplate;
CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
if (pubKey->keyType != ecKey) {
PORT_SetError(SEC_ERROR_BAD_KEY);
break;
}
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
attrs++;
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
attrs++;
PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
attrs++;
templateCount = attrs - keyTemplate;
PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
keyType = PK11_GetKeyType(target,keySize);
key_size = keySize;
symKey->size = keySize;
if (key_size == 0) templateCount--;
mechParams = (CK_ECDH1_DERIVE_PARAMS *)
PORT_ZAlloc(sizeof(CK_ECDH1_DERIVE_PARAMS));
mechParams->kdf = CKD_SHA1_KDF;
mechParams->ulSharedDataLen = 0;
mechParams->pSharedData = NULL;
mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
mechParams->pPublicData = pubKey->u.ec.publicValue.data;
mechanism.mechanism = derive;
mechanism.pParameter = mechParams;
mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);
pk11_EnterKeyMonitor(symKey);
crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
&mechanism, privKey->pkcs11ID, keyTemplate,
templateCount, &symKey->objectID);
pk11_ExitKeyMonitor(symKey);
PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
if (crv == CKR_OK) return symKey;
PORT_SetError( PK11_MapError(crv) );
}
#endif /* NSS_ENABLE_ECC */
}
PK11_FreeSymKey(symKey);

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -114,6 +118,7 @@ static PK11SlotList pk11_aesSlotList,
pk11_rsaSlotList,
pk11_dsaSlotList,
pk11_dhSlotList,
pk11_ecSlotList,
pk11_ideaSlotList,
pk11_sslSlotList,
pk11_tlsSlotList,
@ -1250,6 +1255,7 @@ PK11_InitSlotLists(void)
pk11_initSlotList(&pk11_rsaSlotList);
pk11_initSlotList(&pk11_dsaSlotList);
pk11_initSlotList(&pk11_dhSlotList);
pk11_initSlotList(&pk11_ecSlotList);
pk11_initSlotList(&pk11_ideaSlotList);
pk11_initSlotList(&pk11_sslSlotList);
pk11_initSlotList(&pk11_tlsSlotList);
@ -1273,6 +1279,7 @@ PK11_DestroySlotLists(void)
pk11_freeSlotList(&pk11_rsaSlotList);
pk11_freeSlotList(&pk11_dsaSlotList);
pk11_freeSlotList(&pk11_dhSlotList);
pk11_freeSlotList(&pk11_ecSlotList);
pk11_freeSlotList(&pk11_ideaSlotList);
pk11_freeSlotList(&pk11_sslSlotList);
pk11_freeSlotList(&pk11_tlsSlotList);
@ -1327,6 +1334,11 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type)
case CKM_DH_PKCS_KEY_PAIR_GEN:
case CKM_DH_PKCS_DERIVE:
return &pk11_dhSlotList;
case CKM_ECDSA:
case CKM_ECDSA_SHA1:
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return &pk11_ecSlotList;
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
case CKM_SSL3_SHA1_MAC:
@ -2946,10 +2958,11 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
case CKM_KEA_KEY_DERIVE:
case CKM_KEA_KEY_PAIR_GEN:
return CKK_KEA;
case CKM_ECDSA_KEY_PAIR_GEN:
case CKM_ECDSA:
case CKM_ECDSA_SHA1:
return CKK_ECDSA;
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKK_EC; /* CKK_ECDSA is deprecated */
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_GENERIC_SECRET_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
@ -3109,8 +3122,10 @@ PK11_GetKeyGen(CK_MECHANISM_TYPE type)
case CKM_KEA_KEY_PAIR_GEN:
return CKM_KEA_KEY_PAIR_GEN;
case CKM_ECDSA:
case CKM_ECDSA_KEY_PAIR_GEN:
return CKM_ECDSA_KEY_PAIR_GEN;
case CKM_ECDSA_SHA1:
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKM_EC_KEY_PAIR_GEN;
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
case CKM_SSL3_KEY_AND_MAC_DERIVE:

Просмотреть файл

@ -0,0 +1,672 @@
/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Elliptic Curve Cryptography library.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
*/
#ifdef NSS_ENABLE_ECC
#include "blapi.h"
#include "secoid.h"
#include "secitem.h"
#include "secerr.h"
#include "ec.h"
#define CHECK_OK(func) if (func == NULL) goto cleanup;
/* Initializes a SECItem from a hexadecimal string */
static SECItem *
hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
{
int i = 0;
int byteval = 0;
int tmp = PORT_Strlen(str);
if ((tmp % 2) != 0) return NULL;
item->data = (unsigned char *) PORT_ArenaZAlloc(arena, tmp/2);
if (item->data == NULL) return NULL;
item->len = tmp/2;
while (str[i]) {
if ((str[i] >= '0') && (str[i] <= '9'))
tmp = str[i] - '0';
else if ((str[i] >= 'a') && (str[i] <= 'f'))
tmp = str[i] - 'a' + 10;
else if ((str[i] >= 'A') && (str[i] <= 'F'))
tmp = str[i] - 'A' + 10;
else
return NULL;
byteval = byteval * 16 + tmp;
if ((i % 2) != 0) {
item->data[i/2] = byteval;
byteval = 0;
}
i++;
}
return item;
}
SECStatus
EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
ECParams *params)
{
SECOidTag tag;
SECItem oid = { siBuffer, NULL, 0};
#if EC_DEBUG
int i;
printf("Encoded params in EC_DecodeParams: ");
for (i = 0; i < encodedParams->len; i++) {
printf("%02x:", encodedParams->data[i]);
}
printf("\n");
#endif
if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
return SECFailure;
};
oid.len = encodedParams->len - 2;
oid.data = encodedParams->data + 2;
if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
return SECFailure;
}
params->arena = arena;
params->cofactor = 0;
params->type = ec_params_named;
switch (tag) {
case SEC_OID_ANSIX962_EC_PRIME192V1:
/* Populate params for prime192v1 aka secp192r1
* (the NIST P-192 curve)
*/
params->fieldID.size = 192;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"64210519E59C80E70FA7E9AB72243049" \
"FEB8DEECC146B9B1"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"188DA80EB03090F67CBF20EB43A18800" \
"F4FF0AFD82FF1012" \
"07192B95FFC8DA78631011ED6B24CDD5" \
"73F977A11E794811"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836" \
"146BC9B1B4D22831"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME192V2:
/* Populate params for prime192v2 */
params->fieldID.size = 192;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"CC22D6DFB95C6B25E49C0D6364A4E598" \
"0C393AA21668D953"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"EEA2BAE7E1497842F2DE7769CFE9C989" \
"C072AD696F48034A" \
"6574D11D69B6EC7A672BB82A083DF2F2" \
"B0847DE970B2DE15"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724" \
"DC80418648D8DD31"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME192V3:
/* Populate params for prime192v3 */
params->fieldID.size = 192;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"22123DC2395A05CAA7423DAECCC94760" \
"A7D462256BD56916"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"7D29778100C65A1DA1783716588DCE2B" \
"8B4AEE8E228F1896" \
"38A90F22637337334B49DCB66A6DC8F9" \
"978ACA7648A943B0"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFF7A62D031" \
"C83F4294F640EC13"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME239V1:
/* Populate params for prime239v1 */
params->fieldID.size = 239;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"6B016C3BDCF18941D0D654921475CA71" \
"A9DB2FB27D1D37796185C2942C0A"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"0FFA963CDCA8816CCC33B8642BEDF905" \
"C3D358573D3F27FBBD3B3CB9AAAF" \
"7DEBE8E4E90A5DAE6E4054CA530BA046" \
"54B36818CE226B39FCCB7B02F1AE"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E" \
"5E9A9F5D9071FBD1522688909D0B"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME239V2:
/* Populate params for prime239v2 */
params->fieldID.size = 239;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"617FAB6832576CBBFED50D99F0249C3F" \
"EE58B94BA0038C7AE84C8C832F2C"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"38AF09D98727705120C921BB5E9E2629" \
"6A3CDCF2F35757A0EAFD87B830E7" \
"5B0125E4DBEA0EC7206DA0FC01D9B081" \
"329FB555DE6EF460237DFF8BE4BA"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"7FFFFFFFFFFFFFFFFFFFFFFF800000CF" \
"A7E8594377D414C03821BC582063"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME239V3:
/* Populate params for prime239v3 */
params->fieldID.size = 239;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
"FFFF8000000000007FFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"255705FA2A306654B1F4CB03D6A750A3" \
"0C250102D4988717D9BA15AB6D3E"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"6768AE8E18BB92CFCF005C949AA2C6D9" \
"4853D0E660BBF854B1C9505FE95A" \
"1607E6898F390C06BC1D552BAD226F3B" \
"6FCFE48B6E818499AF18E3ED6CF3"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF97" \
"5DEB41B3A6057C3C432146526551"));
params->cofactor = 1;
break;
case SEC_OID_ANSIX962_EC_PRIME256V1:
/* Populate params for prime256v1 aka secp256r1
* (the NIST P-256 curve)
*/
params->fieldID.size = 256;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFF000000010000000000000000" \
"00000000FFFFFFFFFFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFF000000010000000000000000" \
"00000000FFFFFFFFFFFFFFFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"5AC635D8AA3A93E7B3EBBD55769886BC" \
"651D06B0CC53B0F63BCE3C3E27D2604B"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"6B17D1F2E12C4247F8BCE6E563A440F2" \
"77037D812DEB33A0F4A13945D898C296" \
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" \
"2BCE33576B315ECECBB6406837BF51F5"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFF00000000FFFFFFFFFFFFFFFF" \
"BCE6FAADA7179E84F3B9CAC2FC632551"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP112R1:
/* Populate params for secp112r1 */
params->fieldID.size = 112;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"DB7C2ABF62E35E668076BEAD208B"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"DB7C2ABF62E35E668076BEAD2088"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"659EF8BA043916EEDE8911702B22"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"09487239995A5EE76B55F9C2F098" \
"A89CE5AF8724C0A23E0E0FF77500"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"DB7C2ABF62E35E7628DFAC6561C5"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP112R2:
/* Populate params for secp112r2 */
params->fieldID.size = 112;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"DB7C2ABF62E35E668076BEAD208B"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"6127C24C05F38A0AAAF65C0EF02C"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"51DEF1815DB5ED74FCC34C85D709"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"4BA30AB5E892B4E1649DD0928643" \
"ADCD46F5882E3747DEF36E956E97"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"36DF0AAFD8B8D7597CA10520D04B"));
params->cofactor = 4;
break;
case SEC_OID_SECG_EC_SECP128R1:
/* Populate params for secp128r1 */
params->fieldID.size = 128;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"E87579C11079F43DD824993C2CEE5ED3"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"161FF7528B899B2D0C28607CA52C5B86" \
"CF5AC8395BAFEB13C02DA292DDED7A83"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFE0000000075A30D1B9038A115"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP128R2:
/* Populate params for secp128r2 */
params->fieldID.size = 128;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"D6031998D1B3BBFEBF59CC9BBFF9AEE1"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"5EEEFCA380D02919DC2C6558BB6D8A5D"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"7B6AA5D85E572983E6FB32A7CDEBC140" \
"27B6916A894D3AEE7106FE805FC34B44"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"3FFFFFFF7FFFFFFFBE0024720613B5A3"));
params->cofactor = 4;
break;
case SEC_OID_SECG_EC_SECP160K1:
/* Populate params for secp160k1 */
params->fieldID.size = 160;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFAC73"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"00"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"07"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"3B4C382CE37AA192A4019E763036F4F5" \
"DD4D7EBB" \
"938CF935318FDCED6BC28286531733C3" \
"F03C4FEE"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"0100000000000000000001B8FA16DFAB" \
"9ACA16B6B3"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP160R1:
/* Populate params for secp160r1 */
params->fieldID.size = 160;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"7FFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"7FFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"1C97BEFC54BD7A8B65ACF89F81D4D4AD" \
"C565FA45"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"4A96B5688EF573284664698968C38BB9" \
"13CBFC82" \
"23A628553168947D59DCC91204235137" \
"7AC5FB32"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"0100000000000000000001F4C8F927AE" \
"D3CA752257"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP160R2:
/* Populate params for secp160r1 */
params->fieldID.size = 160;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFAC73"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFAC70"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"B4E134D3FB59EB8BAB57274904664D5A" \
"F50388BA"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"52DCB034293A117E1F4FF11B30F7199D" \
"3144CE6D" \
"FEAFFEF2E331F296E071FA0DF9982CFE" \
"A7D43F2E"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"0100000000000000000000351EE786A8" \
"18F3A1A16B"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP192K1:
/* Populate params for secp192k1 */
params->fieldID.size = 192;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFEFFFFEE37"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"00"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"03"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"DB4FF10EC057E9AE26B07D0280B7F434" \
"1DA5D1B1EAE06C7D" \
"9B2F2F6D9C5628A7844163D015BE8634" \
"4082AA88D95E2F9D"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC17" \
"0F69466A74DEFD8D"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP224K1:
/* Populate params for secp224k1 */
params->fieldID.size = 224;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFEFFFFE56D"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"00"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"05"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"A1455B334DF099DF30FC28A169A467E9" \
"E47075A90F7E650EB6B7A45C" \
"7E089FED7FBA344282CAFBD6F7E319F7" \
"C0B0BD59E2CA4BDB556D61A5"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"010000000000000000000000000001DC" \
"E8D2EC6184CAF0A971769FB1F7"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP224R1:
/* Populate params for secp224r1
* (the NIST P-224 curve)
*/
params->fieldID.size = 224;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"000000000000000000000001"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFFFFFFFFFFFFFFFFFE"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"B4050A850C04B3ABF54132565044B0B7" \
"D7BFD8BA270B39432355FFB4"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"B70E0CBD6BB4BF7F321390B94A03C1D3" \
"56C21122343280D6115C1D21" \
"BD376388B5F723FB4C22DFE6CD4375A0" \
"5A07476444D5819985007E34"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2" \
"E0B8F03E13DD29455C5C2A3D"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP256K1:
/* Populate params for secp256k1 */
params->fieldID.size = 256;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"00"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"07"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"79BE667EF9DCBBAC55A06295CE870B07" \
"029BFCDB2DCE28D959F2815B16F81798" \
"483ADA7726A3C4655DA4FBFC0E1108A8" \
"FD17B448A68554199C47D08FFB10D4B8"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"BAAEDCE6AF48A03BBFD25E8CD0364141"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP384R1:
/* Populate params for secp384r1
* (the NIST P-384 curve)
*/
params->fieldID.size = 384;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFF0000000000000000FFFFFFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
"FFFFFFFF0000000000000000FFFFFFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"B3312FA7E23EE7E4988E056BE3F82D19" \
"181D9C6EFE8141120314088F5013875A" \
"C656398D8A2ED19D2A85C8EDD3EC2AEF"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"AA87CA22BE8B05378EB1C71EF320AD74" \
"6E1D3B628BA79B9859F741E082542A38" \
"5502F25DBF55296C3A545E3872760AB7" \
"3617DE4A96262C6F5D9E98BF9292DC29" \
"F8F41DBD289A147CE9DA3113B5F0B8C0" \
"0A60B1CE1D7E819D7A431D7C90EA0E5F"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFC7634D81F4372DDF" \
"581A0DB248B0A77AECEC196ACCC52973"));
params->cofactor = 1;
break;
case SEC_OID_SECG_EC_SECP521R1:
/* Populate params for secp521r1
* (the NIST P-521 curve)
*/
params->fieldID.size = 521;
params->fieldID.type = ec_field_GFp;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFF"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFC"));
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
"0051953EB9618E1C9A1F929A21A0B685" \
"40EEA2DA725B99B315F3B8B489918EF1" \
"09E156193951EC7E937B1652C0BD3BB1" \
"BF073573DF883D2C34F1EF451FD46B50" \
"3F00"));
CHECK_OK(hexString2SECItem(params->arena, &params->base,
"04" \
"00C6858E06B70404E9CD9E3ECB662395" \
"B4429C648139053FB521F828AF606B4D" \
"3DBAA14B5E77EFE75928FE1DC127A2FF" \
"A8DE3348B3C1856A429BF97E7E31C2E5" \
"BD66" \
"011839296A789A3BC0045C8A5FB42C7D" \
"1BD998F54449579B446817AFBD17273E" \
"662C97EE72995EF42640C550B9013FAD" \
"0761353C7086A272C24088BE94769FD1" \
"6650"));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
"FFFA51868783BF2F966B7FCC0148F709" \
"A5D03BB5C9B8899C47AEBB6FB71E9138" \
"6409"));
params->cofactor = 1;
break;
default:
break;
};
cleanup:
if (!params->cofactor) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
#if EC_DEBUG
printf("Unrecognized curve, returning NULL params\n");
#endif
return SECFailure;
}
return SECSuccess;
}
SECStatus
EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
{
PRArenaPool *arena;
ECParams *params;
SECStatus rv = SECFailure;
/* Initialize an arena for the ECParams structure */
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
return SECFailure;
params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
if (!params) {
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
/* Copy the encoded params */
SECITEM_AllocItem(arena, &(params->DEREncoding),
encodedParams->len);
memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
/* Fill out the rest of the ECParams structure based on
* the encoded params
*/
rv = EC_FillParams(arena, encodedParams, params);
if (rv == SECFailure) {
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
} else {
*ecparams = params;;
return SECSuccess;
}
}
#endif /* NSS_ENABLE_ECC */

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -115,7 +119,8 @@ typedef enum {
NSSLOWKEYNullKey = 0,
NSSLOWKEYRSAKey = 1,
NSSLOWKEYDSAKey = 2,
NSSLOWKEYDHKey = 4
NSSLOWKEYDHKey = 4,
NSSLOWKEYECKey = 5
} NSSLOWKEYType;
/*
@ -128,6 +133,7 @@ struct NSSLOWKEYPublicKeyStr {
RSAPublicKey rsa;
DSAPublicKey dsa;
DHPublicKey dh;
ECPublicKey ec;
} u;
};
typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
@ -144,6 +150,7 @@ struct NSSLOWKEYPrivateKeyStr {
RSAPrivateKey rsa;
DSAPrivateKey dsa;
DHPrivateKey dh;
ECPrivateKey ec;
} u;
};
typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;

Просмотреть файл

@ -62,6 +62,7 @@ CSRCS = \
alghmac.c \
dbinit.c \
dbmshim.c \
ecdecode.c \
fipstest.c \
fipstokn.c \
keydb.c \

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -61,7 +65,11 @@
#include "keydbi.h"
#ifdef NSS_ENABLE_ECC
extern SECStatus EC_FillParams(PRArenaPool *arena,
const SECItem *encodedParams, ECParams *params);
#endif
/*
* ******************** Static data *******************************
*/
@ -226,6 +234,8 @@ struct mechanismList {
#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
#define CKF_EC_PNU CKF_EC_FP | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
#define CK_MAX 0xffffffff
static const struct mechanismList mechanisms[] = {
@ -236,11 +246,11 @@ static const struct mechanismList mechanisms[] = {
* The first argument is the PKCS #11 Mechanism we support.
* The second argument is Mechanism info structure. It includes:
* The minimum key size,
* in bits for RSA, DSA, DH, KEA, RC2 and RC4 * algs.
* in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
* in bytes for RC5, AES, and CAST*
* ignored for DES*, IDEA and FORTEZZA based
* The maximum key size,
* in bits for RSA, DSA, DH, KEA, RC2 and RC4 * algs.
* in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
* in bytes for RC5, AES, and CAST*
* ignored for DES*, IDEA and FORTEZZA based
* Flags
@ -272,6 +282,13 @@ static const struct mechanismList mechanisms[] = {
/* no diffie hellman yet */
{CKM_DH_PKCS_KEY_PAIR_GEN, {128, 1024, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
{CKM_DH_PKCS_DERIVE, {128, 1024, CKF_DERIVE}, PR_TRUE},
#ifdef NSS_ENABLE_ECC
/* -------------------- Elliptic Curve Operations --------------------- */
{CKM_EC_KEY_PAIR_GEN, {112, 571, CKF_GENERATE_KEY_PAIR|CKF_EC_PNU}, PR_TRUE},
{CKM_ECDH1_DERIVE, {112, 571, CKF_DERIVE|CKF_EC_PNU}, PR_TRUE},
{CKM_ECDSA, {112, 571, CKF_SN_VR|CKF_EC_PNU}, PR_TRUE},
{CKM_ECDSA_SHA1, {112, 571, CKF_SN_VR|CKF_EC_PNU}, PR_TRUE},
#endif /* NSS_ENABLE_ECC */
/* ------------------------- RC2 Operations --------------------------- */
{CKM_RC2_KEY_GEN, {1, 128, CKF_GENERATE}, PR_TRUE},
{CKM_RC2_ECB, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE},
@ -1037,6 +1054,21 @@ pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
recover = CK_FALSE;
wrap = CK_FALSE;
break;
#ifdef NSS_ENABLE_ECC
case CKK_EC:
if ( !pk11_hasAttribute(object, CKA_EC_PARAMS)) {
return CKR_TEMPLATE_INCOMPLETE;
}
if ( !pk11_hasAttribute(object, CKA_EC_POINT)) {
return CKR_TEMPLATE_INCOMPLETE;
}
derive = CK_TRUE; /* for ECDH */
verify = CK_TRUE; /* for ECDSA */
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
break;
#endif /* NSS_ENABLE_ECC */
default:
return CKR_ATTRIBUTE_VALUE_INVALID;
}
@ -1111,6 +1143,7 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE
CK_BBOOL encrypt = CK_TRUE;
CK_BBOOL recover = CK_TRUE;
CK_BBOOL wrap = CK_TRUE;
CK_BBOOL derive = CK_FALSE;
CK_BBOOL ckfalse = CK_FALSE;
SECItem mod;
CK_RV crv;
@ -1172,6 +1205,20 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE
recover = CK_FALSE;
wrap = CK_FALSE;
break;
#ifdef NSS_ENABLE_ECC
case CKK_EC:
if ( !pk11_hasAttribute(object, CKA_EC_PARAMS)) {
return CKR_TEMPLATE_INCOMPLETE;
}
if ( !pk11_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
derive = CK_TRUE;
break;
#endif /* NSS_ENABLE_ECC */
default:
return CKR_ATTRIBUTE_VALUE_INVALID;
}
@ -1190,6 +1237,8 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
/* the next two bits get modified only in the key gen and token cases */
crv = pk11_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
&ckfalse,sizeof(CK_BBOOL));
@ -1793,6 +1842,24 @@ NSSLOWKEYPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type,
crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dh.publicValue,
object,CKA_VALUE);
break;
#ifdef NSS_ENABLE_ECC
case CKK_EC:
pubKey->keyType = NSSLOWKEYECKey;
crv = pk11_Attribute2SSecItem(arena,
&pubKey->u.ec.ecParams.DEREncoding,
object,CKA_EC_PARAMS);
if (crv != CKR_OK) break;
/* Fill out the rest of the ecParams structure
* based on the encoded params
*/
if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
&pubKey->u.ec.ecParams) != SECSuccess) break;
crv = pk11_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue,
object,CKA_EC_POINT);
break;
#endif /* NSS_ENABLE_ECC */
default:
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
@ -1899,6 +1966,30 @@ pk11_mkPrivKey(PK11Object *object, CK_KEY_TYPE key_type, CK_RV *crvp)
crv = pk11_Attribute2SSecItem(arena,&privKey->u.dh.publicValue,
object,CKA_NETSCAPE_DB);
break;
#ifdef NSS_ENABLE_ECC
case CKK_EC:
privKey->keyType = NSSLOWKEYECKey;
crv = pk11_Attribute2SSecItem(arena,
&privKey->u.ec.ecParams.DEREncoding,
object,CKA_EC_PARAMS);
if (crv != CKR_OK) break;
/* Fill out the rest of the ecParams structure
* based on the encoded params
*/
if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
&privKey->u.ec.ecParams) != SECSuccess) break;
crv = pk11_Attribute2SSecItem(arena,&privKey->u.ec.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
/* XXX Why does this break handlePrivateKeyObject ?
crv = pk11_Attribute2SSecItem(arena,&privKey->u.ec.publicValue,
object,CKA_NETSCAPE_DB);
*/
break;
#endif /* NSS_ENABLE_ECC */
default:
crv = CKR_KEY_TYPE_INCONSISTENT;
break;

Просмотреть файл

@ -16,8 +16,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -90,6 +94,11 @@ static void pk11_Null(void *data, PRBool freeit)
return;
}
#ifdef NSS_ENABLE_ECC
extern SECStatus EC_DecodeParams(const SECItem *encodedParams,
ECParams **ecparams);
#endif /* NSS_ENABLE_ECC */
/*
* free routines.... Free local type allocated data, and convert
* other free routines to the destroy signature.
@ -1607,6 +1616,41 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
return rv;
}
#ifdef NSS_ENABLE_ECC
static SECStatus
nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
void *dataBuf, unsigned int dataLen)
{
SECItem signature, digest;
NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
signature.data = (unsigned char *)sigBuf;
signature.len = sigLen;
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
}
static SECStatus
nsc_ECDSASignStub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
void *dataBuf, unsigned int dataLen)
{
SECItem signature = { 0 }, digest;
SECStatus rv;
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
(void)SECITEM_AllocItem(NULL, &signature, maxSigLen);
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
*sigLen = signature.len;
PORT_Memcpy(sigBuf, signature.data, signature.len);
SECITEM_FreeItem(&signature, PR_FALSE);
return rv;
}
#endif /* NSS_ENABLE_ECC */
/* NSC_SignInit setups up the signing operations. There are three basic
* types of signing:
* (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
@ -1729,6 +1773,31 @@ finish_rsa:
break;
#ifdef NSS_ENABLE_ECC
case CKM_ECDSA_SHA1:
context->multi = PR_TRUE;
crv = pk11_doSubSHA1(context);
if (crv != CKR_OK) break;
/* fall through */
case CKM_ECDSA:
if (key_type != CKK_EC) {
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
privKey = pk11_GetPrivKey(key,CKK_EC,&crv);
if (privKey == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
context->cipherInfo = privKey;
context->update = (PK11Cipher) nsc_ECDSASignStub;
context->destroy = (privKey == key->objectInfo) ?
(PK11Destroy) pk11_Null:(PK11Destroy)pk11_FreePrivKey;
context->maxLen = MAX_ECKEY_LEN * 2;
break;
#endif /* NSS_ENABLE_ECC */
#define INIT_HMAC_MECH(mmm) \
case CKM_ ## mmm ## _HMAC_GENERAL: \
crv = pk11_doHMACInit(context, HASH_Alg ## mmm ,key, \
@ -2126,7 +2195,28 @@ finish_rsa:
context->verify = (PK11Verify) nsc_DSA_Verify_Stub;
context->destroy = pk11_Null;
break;
#ifdef NSS_ENABLE_ECC
case CKM_ECDSA_SHA1:
context->multi = PR_TRUE;
crv = pk11_doSubSHA1(context);
if (crv != CKR_OK) break;
/* fall through */
case CKM_ECDSA:
if (key_type != CKK_EC) {
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
context->multi = PR_FALSE;
pubKey = pk11_GetPubKey(key,CKK_EC,&crv);
if (pubKey == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
context->cipherInfo = pubKey;
context->verify = (PK11Verify) nsc_ECDSAVerifyStub;
context->destroy = pk11_Null;
break;
#endif /* NSS_ENABLE_ECC */
INIT_HMAC_MECH(MD2)
INIT_HMAC_MECH(MD5)
@ -2872,6 +2962,13 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
int private_value_bits = 0;
DHPrivateKey * dhPriv;
#ifdef NSS_ENABLE_ECC
/* Elliptic Curve Cryptography */
SECItem ecEncodedParams; /* DER Encoded parameters */
ECPrivateKey * ecPriv;
ECParams * ecParams;
#endif /* NSS_ENABLE_ECC */
/*
* now lets create an object to hang the attributes off of
*/
@ -3123,6 +3220,51 @@ dhgn_done:
PORT_FreeArena(dhPriv->arena, PR_TRUE);
break;
#ifdef NSS_ENABLE_ECC
case CKM_EC_KEY_PAIR_GEN:
pk11_DeleteAttributeType(privateKey,CKA_EC_PARAMS);
pk11_DeleteAttributeType(privateKey,CKA_VALUE);
key_type = CKK_EC;
/* extract the necessary parameters and copy them to private keys */
crv = pk11_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey,
CKA_EC_PARAMS);
if (crv != CKR_OK) break;
crv = pk11_AddAttributeType(privateKey, CKA_EC_PARAMS,
pk11_item_expand(&ecEncodedParams));
if (crv != CKR_OK) {
PORT_Free(ecEncodedParams.data);
break;
}
/* Decode ec params before calling EC_NewKey */
rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
PORT_Free(ecEncodedParams.data);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
break;
}
rv = EC_NewKey(ecParams, &ecPriv);
PORT_FreeArena(ecParams->arena, PR_TRUE);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
break;
}
crv = pk11_AddAttributeType(publicKey, CKA_EC_POINT,
pk11_item_expand(&ecPriv->publicValue));
if (crv != CKR_OK) goto ecgn_done;
crv = pk11_AddAttributeType(privateKey, CKA_VALUE,
pk11_item_expand(&ecPriv->privateValue));
ecgn_done:
/* should zeroize, since this function doesn't. */
PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
break;
#endif /* NSS_ENABLE_ECC */
default:
crv = CKR_MECHANISM_INVALID;
}
@ -4778,6 +4920,103 @@ key_and_mac_derive_fail:
break;
}
#ifdef NSS_ENABLE_ECC
case CKM_ECDH1_DERIVE:
case CKM_ECDH1_COFACTOR_DERIVE:
{
SECItem ecScalar, ecPoint;
SECItem tmp;
ECParams *ecParams;
PRBool withCofactor = PR_FALSE;
unsigned char secret_hash[20];
unsigned char *secret;
int secretlen;
CK_ECDH1_DERIVE_PARAMS *mechParams;
/* get params and value attributes */
crv = pk11_Attribute2SecItem(NULL, &tmp, sourceKey,
CKA_EC_PARAMS);
if (crv != CKR_OK) break;
crv = pk11_Attribute2SecItem(NULL, &ecScalar, sourceKey, CKA_VALUE);
if (crv != CKR_OK) {
PORT_Free(tmp.data);
break;
}
/* Check elliptic curve parameters */
rv = EC_DecodeParams(&tmp, &ecParams);
PORT_Free(tmp.data);
if (rv != SECSuccess) {
crv = CKR_TEMPLATE_INCONSISTENT;
PORT_Free(ecScalar.data);
break;
}
/* Check mechanism parameters */
mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter;
if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
((mechParams->kdf == CKD_NULL) &&
((mechParams->ulSharedDataLen != 0) ||
(mechParams->pSharedData != NULL)))) {
crv = CKR_MECHANISM_PARAM_INVALID;
PORT_FreeArena(ecParams->arena, PR_TRUE);
PORT_Free(ecScalar.data);
break;
}
ecPoint.data = mechParams->pPublicData;
ecPoint.len = mechParams->ulPublicDataLen;
if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) {
withCofactor = PR_TRUE;
} else {
/* When not using cofactor derivation, one should
* validate the public key to avoid small subgroup
* attacks.
*/
if (EC_ValidatePublicKey(ecParams, &ecPoint) != SECSuccess) {
crv = CKR_ARGUMENTS_BAD;
PORT_FreeArena(ecParams->arena, PR_TRUE);
PORT_Free(ecScalar.data);
break;
}
}
rv = ECDH_Derive(&ecPoint, ecParams, &ecScalar,
withCofactor, &tmp);
PORT_FreeArena(ecParams->arena, PR_TRUE);
PORT_Free(ecScalar.data);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
break;
}
secret = tmp.data;
secretlen = tmp.len;
if (mechParams->kdf == CKD_SHA1_KDF) {
/* Compute SHA1 hash */
memset(secret_hash, 0, 20);
rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len);
if (rv != SECSuccess) {
PORT_ZFree(tmp.data, tmp.len);
} else {
secret = secret_hash;
secretlen = 20;
}
}
if (rv == SECSuccess) {
pk11_forceAttribute(key, CKA_VALUE, secret, secretlen);
PORT_ZFree(tmp.data, tmp.len);
memset(secret_hash, 0, 20);
} else
crv = CKR_HOST_MEMORY;
break;
}
#endif /* NSS_ENABLE_ECC */
default:
crv = CKR_MECHANISM_INVALID;
}

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -1377,6 +1381,25 @@ typedef struct CK_PKCS5_PBKD2_PARAMS {
typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
/* CK_ECDH1_DERIVE_PARAMS is defined in Section 12.4.4 of
* PKCS#11v2.11. This structure provides parameters for
* the CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE key
* derivation mechanisms.
*/
typedef CK_ULONG CK_EC_KDF_TYPE;
#define CKD_NULL 0x00000001
#define CKD_SHA1_KDF 0x00000002
typedef struct CK_ECDH1_DERIVE_PARAMS {
CK_EC_KDF_TYPE kdf;
CK_ULONG ulSharedDataLen;
CK_BYTE_PTR pSharedData;
CK_ULONG ulPublicDataLen;
CK_BYTE_PTR pPublicData;
} CK_ECDH1_DERIVE_PARAMS;
typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
/* Netscape Specific defines */
#include "pkcs11n.h"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -19,7 +19,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -33,7 +37,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: ssl3prot.h,v 1.2 2001-09-18 01:59:19 nelsonb%netscape.com Exp $
* $Id: ssl3prot.h,v 1.3 2003-02-27 01:31:30 nelsonb%netscape.com Exp $
*/
#ifndef __ssl3proto_h_
@ -203,7 +207,11 @@ typedef enum {
kea_dh_anon,
kea_dh_anon_export,
kea_fortezza,
kea_rsa_fips
kea_rsa_fips,
kea_ecdh_ecdsa,
kea_ecdhe_ecdsa,
kea_ecdh_rsa,
kea_ecdhe_rsa
} SSL3KeyExchangeAlgorithm;
typedef struct {

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslcon.c,v 1.19 2002-02-27 04:40:15 nelsonb%netscape.com Exp $
* $Id: sslcon.c,v 1.20 2003-02-27 01:31:30 nelsonb%netscape.com Exp $
*/
#include "nssrenam.h"
@ -2061,7 +2065,7 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
ss->sec.authAlgorithm = ssl_sign_rsa;
ss->sec.keaType = ssl_kea_rsa;
ss->sec.keaKeyBits = \
ss->sec.authKeyBits = SECKEY_PublicKeyStrength(serverKey) * BPB;
ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
/* Choose a compatible cipher with the server */
nc = csLen / 3;

Просмотреть файл

@ -19,8 +19,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -34,7 +38,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslenum.c,v 1.6 2002-08-09 21:53:17 nelsonb%netscape.com Exp $
* $Id: sslenum.c,v 1.7 2003-02-27 01:31:32 nelsonb%netscape.com Exp $
*/
#include "ssl.h"
@ -45,13 +49,27 @@ const PRUint16 SSL_ImplementedCiphers[] = {
/* 256-bit */
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
#endif /* NSS_ENABLE_ECC */
TLS_RSA_WITH_AES_256_CBC_SHA,
/* 128-bit */
SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
#endif /* NSS_ENABLE_ECC */
TLS_DHE_DSS_WITH_RC4_128_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_RC4_128_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
#endif /* NSS_ENABLE_ECC */
SSL_RSA_WITH_RC4_128_MD5,
SSL_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
@ -59,6 +77,10 @@ const PRUint16 SSL_ImplementedCiphers[] = {
/* 112-bit 3DES */
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
#endif /* NSS_ENABLE_ECC */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
@ -68,6 +90,10 @@ const PRUint16 SSL_ImplementedCiphers[] = {
/* 56-bit DES "domestic" cipher suites */
SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_DHE_DSS_WITH_DES_CBC_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_DES_CBC_SHA,
TLS_ECDH_ECDSA_WITH_DES_CBC_SHA,
#endif /* NSS_ENABLE_ECC */
SSL_RSA_FIPS_WITH_DES_CBC_SHA,
SSL_RSA_WITH_DES_CBC_SHA,
@ -81,6 +107,10 @@ const PRUint16 SSL_ImplementedCiphers[] = {
/* ciphersuites with no encryption */
SSL_FORTEZZA_DMS_WITH_NULL_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_NULL_SHA,
TLS_ECDH_ECDSA_WITH_NULL_SHA,
#endif /* NSS_ENABLE_ECC */
SSL_RSA_WITH_NULL_SHA,
SSL_RSA_WITH_NULL_MD5,

Просмотреть файл

@ -19,8 +19,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -34,7 +38,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslimpl.h,v 1.29 2003-02-15 01:21:24 relyea%netscape.com Exp $
* $Id: sslimpl.h,v 1.30 2003-02-27 01:31:34 nelsonb%netscape.com Exp $
*/
#ifndef __sslimpl_h_
@ -72,6 +76,7 @@ typedef SSLSignType SSL3SignType;
#define sign_null ssl_sign_null
#define sign_rsa ssl_sign_rsa
#define sign_dsa ssl_sign_dsa
#define sign_ecdsa ssl_sign_ecdsa
#define calg_null ssl_calg_null
#define calg_rc4 ssl_calg_rc4
@ -254,7 +259,11 @@ typedef struct {
#endif
} ssl3CipherSuiteCfg;
#ifdef NSS_ENABLE_ECC
#define ssl_V3_SUITES_IMPLEMENTED 40
#else
#define ssl_V3_SUITES_IMPLEMENTED 26
#endif /* NSS_ENABLE_ECC */
typedef struct sslOptionsStr {
unsigned int useSecurity : 1; /* 1 */
@ -972,7 +981,7 @@ const unsigned char * preferredCipher;
sslHandshakingType handshaking;
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
};
@ -1181,6 +1190,10 @@ int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags);
*/
extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss);
#ifdef NSS_ENABLE_ECC
extern SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss);
#endif /* NSS_ENABLE_ECC */
extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -30,7 +34,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslinfo.c,v 1.5 2002-08-09 21:53:17 nelsonb%netscape.com Exp $
* $Id: sslinfo.c,v 1.6 2003-02-27 01:31:34 nelsonb%netscape.com Exp $
*/
#include "ssl.h"
#include "sslimpl.h"
@ -106,10 +110,13 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
#define S_DSA "DSA", ssl_auth_dsa
#define S_RSA "RSA", ssl_auth_rsa
#define S_KEA "KEA", ssl_auth_kea
#define S_ECDSA "ECDSA", ssl_auth_ecdsa
#define K_DHE "DHE", kt_dh
#define K_RSA "RSA", kt_rsa
#define K_KEA "KEA", kt_kea
#define K_ECDH "ECDH", kt_ecdh
#define K_ECDHE "ECDHE", kt_ecdh
#define C_AES "AES", calg_aes
#define C_RC4 "RC4", calg_rc4
@ -164,6 +171,27 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
#ifdef NSS_ENABLE_ECC
/* ECC cipher suites */
{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_DES_CBC_SHA), S_ECDSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_DES_CBC_SHA), S_RSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 0, 0, 0, },
#endif /* NSS_ENABLE_ECC */
/* SSL 2 table */
{0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
{0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },

Просмотреть файл

@ -20,7 +20,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -34,7 +38,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslproto.h,v 1.3 2001-09-21 03:07:35 nelsonb%netscape.com Exp $
* $Id: sslproto.h,v 1.4 2003-02-27 01:31:35 nelsonb%netscape.com Exp $
*/
#ifndef __sslproto_h_
@ -161,6 +165,29 @@
#define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065
#define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066
#ifdef NSS_ENABLE_ECC
/* "Experimental" ECC cipher suites.
** XXX These numbers might change before the current IETF draft
** on ECC cipher suites for TLS becomes an RFC.
*/
#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0x0047
#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0x0048
#define TLS_ECDH_ECDSA_WITH_DES_CBC_SHA 0x0049
#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0x004A
#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x004B
#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x004C
#define TLS_ECDH_RSA_WITH_NULL_SHA 0x004D
#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0x004E
#define TLS_ECDH_RSA_WITH_DES_CBC_SHA 0x004F
#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0x0050
#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0051
#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0052
#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0077
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0078
#endif /* NSS_ENABLE_ECC */
/* Netscape "experimental" cipher suites. */
#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslsecur.c,v 1.21 2003-02-15 01:21:25 relyea%netscape.com Exp $
* $Id: sslsecur.c,v 1.22 2003-02-27 01:31:35 nelsonb%netscape.com Exp $
*/
#include "cert.h"
#include "secitem.h"
@ -639,7 +643,7 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
pubKey = CERT_ExtractPublicKey(cert);
if (!pubKey)
goto loser;
sc->serverKeyBits = SECKEY_PublicKeyStrength(pubKey) * BPB;
sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey);
SECKEY_DestroyPublicKey(pubKey);
pubKey = NULL;
}

Просмотреть файл

@ -20,8 +20,12 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Stephen Henson <stephen.henson@gemplus.com>
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -35,7 +39,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslsock.c,v 1.30 2002-08-09 21:53:17 nelsonb%netscape.com Exp $
* $Id: sslsock.c,v 1.31 2003-02-27 01:31:35 nelsonb%netscape.com Exp $
*/
#include "seccomon.h"
#include "cert.h"
@ -93,6 +97,22 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
{ TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
{ TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
{ TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
#endif /* NSS_ENABLE_ECC */
{ 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }
};

Просмотреть файл

@ -18,7 +18,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -32,7 +36,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: sslt.h,v 1.3 2002-03-22 21:43:43 nelsonb%netscape.com Exp $
* $Id: sslt.h,v 1.4 2003-02-27 01:31:35 nelsonb%netscape.com Exp $
*/
#ifndef __sslt_h_
@ -63,6 +67,7 @@ typedef enum {
ssl_kea_rsa = 1,
ssl_kea_dh = 2,
ssl_kea_fortezza = 3,
ssl_kea_ecdh = 4,
ssl_kea_size /* number of ssl_kea_ algorithms */
} SSLKEAType;
@ -75,19 +80,22 @@ typedef enum {
#define kt_rsa ssl_kea_rsa
#define kt_dh ssl_kea_dh
#define kt_fortezza ssl_kea_fortezza
#define kt_ecdh ssl_kea_ecdh
#define kt_kea_size ssl_kea_size
typedef enum {
ssl_sign_null = 0,
ssl_sign_rsa = 1,
ssl_sign_dsa = 2
ssl_sign_dsa = 2,
ssl_sign_ecdsa = 3
} SSLSignType;
typedef enum {
ssl_auth_null = 0,
ssl_auth_rsa = 1,
ssl_auth_dsa = 2,
ssl_auth_kea = 3
ssl_auth_kea = 3,
ssl_auth_ecdsa = 4
} SSLAuthType;
typedef enum {

Просмотреть файл

@ -185,7 +185,12 @@ SEC_ERROR_BAD_TEMPLATE = (SEC_ERROR_BASE + 136),
SEC_ERROR_CRL_NOT_FOUND = (SEC_ERROR_BASE + 137),
SEC_ERROR_REUSED_ISSUER_AND_SERIAL = (SEC_ERROR_BASE + 138),
SEC_ERROR_BUSY = (SEC_ERROR_BASE + 139),
SEC_ERROR_EXTRA_INPUT = (SEC_ERROR_BASE + 140)
SEC_ERROR_EXTRA_INPUT = (SEC_ERROR_BASE + 140),
/* error codes used by elliptic curve code */
SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE = (SEC_ERROR_BASE + 141),
SEC_ERROR_UNSUPPORTED_EC_POINT_FORM = (SEC_ERROR_BASE + 142),
SEC_ERROR_UNRECOGNIZED_OID = (SEC_ERROR_BASE + 143)
} SECErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -153,6 +157,14 @@
/* { 1.3.6.1.4.1.311 } */
#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
#define CERTICOM_OID 0x2b, 0x81, 0x04
#define SECG_OID CERTICOM_OID, 0x00
#define ANSI_X962_OID 0x2a, 0x86, 0x48, 0xce, 0x3d
#define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03
#define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00
#define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01
#define CONST_OID static const unsigned char
CONST_OID md2[] = { DIGEST, 0x02 };
@ -425,6 +437,36 @@ CONST_OID sha256[] = { SHAXXX, 1 };
CONST_OID sha384[] = { SHAXXX, 2 };
CONST_OID sha512[] = { SHAXXX, 3 };
CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 };
CONST_OID ansix962ECDSASignaturewithSHA1Digest[] = { ANSI_X962_OID, 0x04, 0x01 };
/* ANSI X9.62 prime curve OIDs */
/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
* same as secp256r1
*/
CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
/* SECG prime curve OIDs */
CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
#ifndef SECOID_NO_STRINGS
#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
@ -1046,6 +1088,101 @@ const static SECOidData oids[] = {
OD( aes256_KEY_WRAP, SEC_OID_AES_256_KEY_WRAP,
"AES-256 Key Wrap", CKM_NETSCAPE_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
/* Elliptic Curve Cryptography (ECC) OIDs */
OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY,
"X9.62 elliptic curve public key", CKM_ECDH1_DERIVE,
INVALID_CERT_EXTENSION ),
OD( ansix962ECDSASignaturewithSHA1Digest,
SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST,
"X9.62 ECDSA signature with SHA1", CKM_ECDSA_SHA1,
INVALID_CERT_EXTENSION ),
/* Named curves */
/* ANSI X9.62 named elliptic curves (prime field) */
OD( ansiX962prime192v1, SEC_OID_ANSIX962_EC_PRIME192V1,
"ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime192v2, SEC_OID_ANSIX962_EC_PRIME192V2,
"ANSI X9.62 elliptic curve prime192v2",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime192v3, SEC_OID_ANSIX962_EC_PRIME192V3,
"ANSI X9.62 elliptic curve prime192v3",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime239v1, SEC_OID_ANSIX962_EC_PRIME239V1,
"ANSI X9.62 elliptic curve prime239v1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime239v2, SEC_OID_ANSIX962_EC_PRIME239V2,
"ANSI X9.62 elliptic curve prime239v2",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime239v3, SEC_OID_ANSIX962_EC_PRIME239V3,
"ANSI X9.62 elliptic curve prime239v3",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( ansiX962prime256v1, SEC_OID_ANSIX962_EC_PRIME256V1,
"ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
/* SECG named elliptic curves (prime field) */
OD( secgECsecp112r1, SEC_OID_SECG_EC_SECP112R1,
"SECG elliptic curve secp112r1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp112r2, SEC_OID_SECG_EC_SECP112R2,
"SECG elliptic curve secp112r2",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp128r1, SEC_OID_SECG_EC_SECP128R1,
"SECG elliptic curve secp128r1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp128r2, SEC_OID_SECG_EC_SECP128R2,
"SECG elliptic curve secp128r2",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp160k1, SEC_OID_SECG_EC_SECP160K1,
"SECG elliptic curve secp160k1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp160r1, SEC_OID_SECG_EC_SECP160R1,
"SECG elliptic curve secp160r1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp160r2, SEC_OID_SECG_EC_SECP160R2,
"SECG elliptic curve secp160r2",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp192k1, SEC_OID_SECG_EC_SECP192K1,
"SECG elliptic curve secp192k1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp224k1, SEC_OID_SECG_EC_SECP224K1,
"SECG elliptic curve secp224k1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp224r1, SEC_OID_SECG_EC_SECP224R1,
"SECG elliptic curve secp224r1 (aka NIST P-224)",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp256k1, SEC_OID_SECG_EC_SECP256K1,
"SECG elliptic curve secp256k1",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp384r1, SEC_OID_SECG_EC_SECP384R1,
"SECG elliptic curve secp384r1 (aka NIST P-384)",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
OD( secgECsecp521r1, SEC_OID_SECG_EC_SECP521R1,
"SECG elliptic curve secp521r1 (aka NIST P-521)",
CKM_INVALID_MECHANISM,
INVALID_CERT_EXTENSION ),
};
/*

Просмотреть файл

@ -16,7 +16,11 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@ -36,7 +40,7 @@
/*
* secoidt.h - public data structures for ASN.1 OID functions
*
* $Id: secoidt.h,v 1.11 2003-01-22 04:35:54 nelsonb%netscape.com Exp $
* $Id: secoidt.h,v 1.12 2003-02-27 01:31:38 nelsonb%netscape.com Exp $
*/
#include "secitem.h"
@ -308,9 +312,42 @@ typedef enum {
SEC_OID_AES_192_KEY_WRAP = 198,
SEC_OID_AES_256_KEY_WRAP = 199,
/* Elliptic Curve Cryptography (ECC) OIDs */
SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200,
SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST = 201,
/* ANSI X9.62 named elliptic curves (prime field) */
SEC_OID_ANSIX962_EC_PRIME192V1 = 202,
SEC_OID_ANSIX962_EC_PRIME192V2 = 203,
SEC_OID_ANSIX962_EC_PRIME192V3 = 204,
SEC_OID_ANSIX962_EC_PRIME239V1 = 205,
SEC_OID_ANSIX962_EC_PRIME239V2 = 206,
SEC_OID_ANSIX962_EC_PRIME239V3 = 207,
SEC_OID_ANSIX962_EC_PRIME256V1 = 208,
/* SECG named elliptic curves (prime field) */
SEC_OID_SECG_EC_SECP112R1 = 209,
SEC_OID_SECG_EC_SECP112R2 = 210,
SEC_OID_SECG_EC_SECP128R1 = 211,
SEC_OID_SECG_EC_SECP128R2 = 212,
SEC_OID_SECG_EC_SECP160K1 = 213,
SEC_OID_SECG_EC_SECP160R1 = 214,
SEC_OID_SECG_EC_SECP160R2 = 215,
SEC_OID_SECG_EC_SECP192K1 = 216,
/* SEC_OID_SECG_EC_SECP192R1 is SEC_OID_ANSIX962_EC_PRIME192V1 */
SEC_OID_SECG_EC_SECP224K1 = 217,
SEC_OID_SECG_EC_SECP224R1 = 218,
SEC_OID_SECG_EC_SECP256K1 = 219,
/* SEC_OID_SECG_EC_SECP256R1 is SEC_OID_ANSIX962_EC_PRIME256V1 */
SEC_OID_SECG_EC_SECP384R1 = 220,
SEC_OID_SECG_EC_SECP521R1 = 221,
SEC_OID_TOTAL
} SECOidTag;
#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
/* fake OID for DSS sign/verify */
#define SEC_OID_SHA SEC_OID_MISS_DSS