зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
c5c0fb381e
Коммит
42fae25f24
|
@ -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.")
|
||||
|
|
|
@ -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
|
||||
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
@ -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.
|
||||
*
|
||||
* 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, ©k->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,©k->u.ec.DEREncodedParams,
|
||||
&pubk->u.ec.DEREncodedParams);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena,©k->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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"64210519E59C80E70FA7E9AB72243049" \
|
||||
"FEB8DEECC146B9B1"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"188DA80EB03090F67CBF20EB43A18800" \
|
||||
"F4FF0AFD82FF1012" \
|
||||
"07192B95FFC8DA78631011ED6B24CDD5" \
|
||||
"73F977A11E794811"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"CC22D6DFB95C6B25E49C0D6364A4E598" \
|
||||
"0C393AA21668D953"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"EEA2BAE7E1497842F2DE7769CFE9C989" \
|
||||
"C072AD696F48034A" \
|
||||
"6574D11D69B6EC7A672BB82A083DF2F2" \
|
||||
"B0847DE970B2DE15"));
|
||||
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"22123DC2395A05CAA7423DAECCC94760" \
|
||||
"A7D462256BD56916"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"7D29778100C65A1DA1783716588DCE2B" \
|
||||
"8B4AEE8E228F1896" \
|
||||
"38A90F22637337334B49DCB66A6DC8F9" \
|
||||
"978ACA7648A943B0"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"6B016C3BDCF18941D0D654921475CA71" \
|
||||
"A9DB2FB27D1D37796185C2942C0A"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"0FFA963CDCA8816CCC33B8642BEDF905" \
|
||||
"C3D358573D3F27FBBD3B3CB9AAAF" \
|
||||
"7DEBE8E4E90A5DAE6E4054CA530BA046" \
|
||||
"54B36818CE226B39FCCB7B02F1AE"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"617FAB6832576CBBFED50D99F0249C3F" \
|
||||
"EE58B94BA0038C7AE84C8C832F2C"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"38AF09D98727705120C921BB5E9E2629" \
|
||||
"6A3CDCF2F35757A0EAFD87B830E7" \
|
||||
"5B0125E4DBEA0EC7206DA0FC01D9B081" \
|
||||
"329FB555DE6EF460237DFF8BE4BA"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF" \
|
||||
"FFFF8000000000007FFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"255705FA2A306654B1F4CB03D6A750A3" \
|
||||
"0C250102D4988717D9BA15AB6D3E"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"6768AE8E18BB92CFCF005C949AA2C6D9" \
|
||||
"4853D0E660BBF854B1C9505FE95A" \
|
||||
"1607E6898F390C06BC1D552BAD226F3B" \
|
||||
"6FCFE48B6E818499AF18E3ED6CF3"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFF000000010000000000000000" \
|
||||
"00000000FFFFFFFFFFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFF000000010000000000000000" \
|
||||
"00000000FFFFFFFFFFFFFFFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"5AC635D8AA3A93E7B3EBBD55769886BC" \
|
||||
"651D06B0CC53B0F63BCE3C3E27D2604B"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"6B17D1F2E12C4247F8BCE6E563A440F2" \
|
||||
"77037D812DEB33A0F4A13945D898C296" \
|
||||
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" \
|
||||
"2BCE33576B315ECECBB6406837BF51F5"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"DB7C2ABF62E35E668076BEAD208B"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"DB7C2ABF62E35E668076BEAD2088"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"659EF8BA043916EEDE8911702B22"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"09487239995A5EE76B55F9C2F098" \
|
||||
"A89CE5AF8724C0A23E0E0FF77500"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"DB7C2ABF62E35E668076BEAD208B"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"6127C24C05F38A0AAAF65C0EF02C"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"51DEF1815DB5ED74FCC34C85D709"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"4BA30AB5E892B4E1649DD0928643" \
|
||||
"ADCD46F5882E3747DEF36E956E97"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"E87579C11079F43DD824993C2CEE5ED3"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"161FF7528B899B2D0C28607CA52C5B86" \
|
||||
"CF5AC8395BAFEB13C02DA292DDED7A83"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"D6031998D1B3BBFEBF59CC9BBFF9AEE1"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"5EEEFCA380D02919DC2C6558BB6D8A5D"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"7B6AA5D85E572983E6FB32A7CDEBC140" \
|
||||
"27B6916A894D3AEE7106FE805FC34B44"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFAC73"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"00"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"07"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"3B4C382CE37AA192A4019E763036F4F5" \
|
||||
"DD4D7EBB" \
|
||||
"938CF935318FDCED6BC28286531733C3" \
|
||||
"F03C4FEE"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"7FFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"7FFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"1C97BEFC54BD7A8B65ACF89F81D4D4AD" \
|
||||
"C565FA45"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"4A96B5688EF573284664698968C38BB9" \
|
||||
"13CBFC82" \
|
||||
"23A628553168947D59DCC91204235137" \
|
||||
"7AC5FB32"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFAC73"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFAC70"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"B4E134D3FB59EB8BAB57274904664D5A" \
|
||||
"F50388BA"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"52DCB034293A117E1F4FF11B30F7199D" \
|
||||
"3144CE6D" \
|
||||
"FEAFFEF2E331F296E071FA0DF9982CFE" \
|
||||
"A7D43F2E"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFEFFFFEE37"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"00"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"03"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"DB4FF10EC057E9AE26B07D0280B7F434" \
|
||||
"1DA5D1B1EAE06C7D" \
|
||||
"9B2F2F6D9C5628A7844163D015BE8634" \
|
||||
"4082AA88D95E2F9D"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFEFFFFE56D"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"00"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"05"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"A1455B334DF099DF30FC28A169A467E9" \
|
||||
"E47075A90F7E650EB6B7A45C" \
|
||||
"7E089FED7FBA344282CAFBD6F7E319F7" \
|
||||
"C0B0BD59E2CA4BDB556D61A5"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"000000000000000000000001"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFE"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"B4050A850C04B3ABF54132565044B0B7" \
|
||||
"D7BFD8BA270B39432355FFB4"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"B70E0CBD6BB4BF7F321390B94A03C1D3" \
|
||||
"56C21122343280D6115C1D21" \
|
||||
"BD376388B5F723FB4C22DFE6CD4375A0" \
|
||||
"5A07476444D5819985007E34"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"00"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"07"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"79BE667EF9DCBBAC55A06295CE870B07" \
|
||||
"029BFCDB2DCE28D959F2815B16F81798" \
|
||||
"483ADA7726A3C4655DA4FBFC0E1108A8" \
|
||||
"FD17B448A68554199C47D08FFB10D4B8"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFF0000000000000000FFFFFFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" \
|
||||
"FFFFFFFF0000000000000000FFFFFFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"B3312FA7E23EE7E4988E056BE3F82D19" \
|
||||
"181D9C6EFE8141120314088F5013875A" \
|
||||
"C656398D8A2ED19D2A85C8EDD3EC2AEF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"AA87CA22BE8B05378EB1C71EF320AD74" \
|
||||
"6E1D3B628BA79B9859F741E082542A38" \
|
||||
"5502F25DBF55296C3A545E3872760AB7" \
|
||||
"3617DE4A96262C6F5D9E98BF9292DC29" \
|
||||
"F8F41DBD289A147CE9DA3113B5F0B8C0" \
|
||||
"0A60B1CE1D7E819D7A431D7C90EA0E5F"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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, ¶ms->fieldID.u.prime,
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFF"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
|
||||
"FFFC"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
"0051953EB9618E1C9A1F929A21A0B685" \
|
||||
"40EEA2DA725B99B315F3B8B489918EF1" \
|
||||
"09E156193951EC7E937B1652C0BD3BB1" \
|
||||
"BF073573DF883D2C34F1EF451FD46B50" \
|
||||
"3F00"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base,
|
||||
"04" \
|
||||
"00C6858E06B70404E9CD9E3ECB662395" \
|
||||
"B4429C648139053FB521F828AF606B4D" \
|
||||
"3DBAA14B5E77EFE75928FE1DC127A2FF" \
|
||||
"A8DE3348B3C1856A429BF97E7E31C2E5" \
|
||||
"BD66" \
|
||||
"011839296A789A3BC0045C8A5FB42C7D" \
|
||||
"1BD998F54449579B446817AFBD17273E" \
|
||||
"662C97EE72995EF42640C550B9013FAD" \
|
||||
"0761353C7086A272C24088BE94769FD1" \
|
||||
"6650"));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->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.
|
||||
*
|
||||
* 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,6 +65,10 @@
|
|||
|
||||
#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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче