# HG changeset patch
# User Tobias Wagner <tobias.wagner@n-design.de>
# Date 1513340605 -3600
#      Fri Dec 15 13:23:25 2017 +0100
# Branch RFC-5639-without-twisted-curves
# Node ID 427c17843c6bce9a2a233225b81f0d0f99c28cd2
# Parent  65464a3074083e84441a216e9b94d8f9ad4c464f
Introduce brainpoolP*r1 from RFC 5639 curves to SunEC

diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/ec.h b/src/jdk.crypto.ec/share/native/libsunec/impl/ec.h
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ec.h
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ec.h
@@ -47,5 +47,6 @@
 
 #define ANSI_X962_CURVE_OID_TOTAL_LEN    10
 #define SECG_CURVE_OID_TOTAL_LEN          7
+#define BRAINPOOL_CURVE_OID_TOTAL_LEN    11
 
 #endif /* __ec_h_ */
diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c b/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c
@@ -172,7 +172,8 @@
 #endif
 
     if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
-        (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
+    	(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN) &&
+    	(encodedParams->len != BRAINPOOL_CURVE_OID_TOTAL_LEN)) {
             PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
             return SECFailure;
     };
@@ -565,6 +566,48 @@
             params, kmflag) );
         break;
 
+    case ECCurve_BrainpoolP160r1:
+        /* Populate params for brainpoolP160r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP160r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP192r1:
+        /* Populate params for brainpoolP192r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP192r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP224r1:
+        /* Populate params for brainpoolP224r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP224r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP256r1:
+        /* Populate params for brainpoolP256r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP256r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP320r1:
+        /* Populate params for brainpoolP320r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP320r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP384r1:
+        /* Populate params for brainpoolP384r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP384r1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_BrainpoolP512r1:
+    	/* Populate params for brainpoolP512r1 */
+    	CHECK_SEC_OK( gf_populate_params(ECCurve_BrainpoolP512r1, ec_field_GFp,
+    		params, kmflag) );
+    	break;
+
     default:
         break;
     };
diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-curve.h b/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-curve.h
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-curve.h
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-curve.h
@@ -623,6 +623,76 @@
         "0100000000000000000001CDC98AE0E2DE574ABF33", 1
 };
 
+static const ECCurveParams ecCurve_BrainpoolP160r1 = {
+	"brainpoolP160r1", ECField_GFp, 160,
+	"E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+	"340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+	"1E589A8595423412134FAA2DBDEC95C8D8675E58",
+	"BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+	"1667CB477A1A8EC338F94741669C976316DA6321",
+	"E95E4A5F737059DC60DF5991D45029409E60FC09", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP192r1 = {
+	"brainpoolP192r1", ECField_GFp, 192,
+	"C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+	"6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+	"469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+	"C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+	"14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+	"C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP224r1 = {
+	"brainpoolP224r1", ECField_GFp, 224,
+	"D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+	"68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+	"2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+	"0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+	"58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+	"D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP256r1 = {
+	"brainpoolP256r1", ECField_GFp, 256,
+	"A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+	"7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+	"26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+	"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+	"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+	"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP320r1 = {
+	"brainpoolP320r1", ECField_GFp, 320,
+	"D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+	"3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+	"520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+	"43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+	"14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+	"D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP384r1 = {
+	"brainpoolP384r1", ECField_GFp, 384,
+	"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+	"7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+	"04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+	"1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+	"8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+	"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 1
+};
+
+static const ECCurveParams ecCurve_BrainpoolP512r1 = {
+	"brainpoolP512r1", ECField_GFp, 512,
+	"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+	"7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+	"3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+	"81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+	"7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+	"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 1
+};
+
 /* mapping between ECCurveName enum and pointers to ECCurveParams */
 static const ECCurveParams *ecCurve_map[] = {
     NULL,                               /* ECCurve_noName */
@@ -683,6 +753,13 @@
     &ecCurve_WTLS_1,                    /* ECCurve_WTLS_1 */
     &ecCurve_WTLS_8,                    /* ECCurve_WTLS_8 */
     &ecCurve_WTLS_9,                    /* ECCurve_WTLS_9 */
+    &ecCurve_BrainpoolP160r1,		/* ECCurve_BrainpoolP160r1 */
+    &ecCurve_BrainpoolP192r1,		/* ECCurve_BrainpoolP192r1 */
+    &ecCurve_BrainpoolP224r1,		/* ECCurve_BrainpoolP224r1 */
+    &ecCurve_BrainpoolP256r1,		/* ECCurve_BrainpoolP256r1 */
+    &ecCurve_BrainpoolP320r1,		/* ECCurve_BrainpoolP320r1 */
+    &ecCurve_BrainpoolP384r1,		/* ECCurve_brainpoolP384r1 */
+    &ecCurve_BrainpoolP512r1,		/* ECCurve_brainpoolP512r1 */
     NULL                                /* ECCurve_pastLastCurve */
 };
 
diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-exp.h b/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-exp.h
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-exp.h
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ecl-exp.h
@@ -160,6 +160,15 @@
         /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
         /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
         /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
+        
+        /* TeleTrusT ECC Brainpool prime curves */
+        ECCurve_BrainpoolP160r1,
+        ECCurve_BrainpoolP192r1,
+        ECCurve_BrainpoolP224r1,
+        ECCurve_BrainpoolP256r1,
+        ECCurve_BrainpoolP320r1,
+        ECCurve_BrainpoolP384r1,
+        ECCurve_BrainpoolP512r1,
 
         ECCurve_pastLastCurve
 } ECCurveName;
diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c b/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c
--- a/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c
+++ b/src/jdk.crypto.ec/share/native/libsunec/impl/oid.c
@@ -63,6 +63,10 @@
 #define ANSI_X962_GF2m_OID      ANSI_X962_CURVE_OID, 0x00
 #define ANSI_X962_GFp_OID       ANSI_X962_CURVE_OID, 0x01
 
+#define TELETRUST_ALGO_OID		0x2b, 0x24, 0x03
+#define ECC_BRAINPOOL			TELETRUST_ALGO_OID, 0x03, 0x02, 0x08
+#define ECC_BRAINPOOL_EC_V1		ECC_BRAINPOOL, 0x01, 0x01
+
 #define CONST_OID static const unsigned char
 
 /* ANSI X9.62 prime curve OIDs */
@@ -134,6 +138,15 @@
 CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
 CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
 
+/* TeleTrusT ECC Brainpool prime curve OIDs */
+CONST_OID brainpoolP160r1[] = { ECC_BRAINPOOL_EC_V1, 0x01 };
+CONST_OID brainpoolP192r1[] = { ECC_BRAINPOOL_EC_V1, 0x03 };
+CONST_OID brainpoolP224r1[] = { ECC_BRAINPOOL_EC_V1, 0x05 };
+CONST_OID brainpoolP256r1[] = { ECC_BRAINPOOL_EC_V1, 0x07 };
+CONST_OID brainpoolP320r1[] = { ECC_BRAINPOOL_EC_V1, 0x09 };
+CONST_OID brainpoolP384r1[] = { ECC_BRAINPOOL_EC_V1, 0x0b };
+CONST_OID brainpoolP512r1[] = { ECC_BRAINPOOL_EC_V1, 0x0d };
+
 #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 }
@@ -409,6 +422,53 @@
         INVALID_CERT_EXTENSION )
 };
 
+static SECOidData BRAINPOOL_oids[] = {
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP160r1, ECCurve_BrainpoolP160r1,
+        "brainpoolP160r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP192r1, ECCurve_BrainpoolP192r1,
+        "brainpoolP192r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP224r1, ECCurve_BrainpoolP224r1,
+        "brainpoolP224r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP256r1, ECCurve_BrainpoolP256r1,
+        "brainpoolP256r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP320r1, ECCurve_BrainpoolP320r1,
+        "brainpoolP320r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP384r1, ECCurve_BrainpoolP384r1,
+        "brainpoolP384r1 domain parameter set",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+	{ { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+	OD( brainpoolP512r1, ECCurve_BrainpoolP512r1,
+		"brainpoolP512r1 domain parameter set",
+		CKM_INVALID_MECHANISM,
+		INVALID_CERT_EXTENSION ),
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+		"Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION }
+};
+
 SECOidData *
 SECOID_FindOID(const SECItem *oid)
 {
@@ -433,6 +493,12 @@
         po = &SECG_oids[oid->data[4]];
         if (memcmp(oid->data, po->oid.data, 5) == 0)
                 ret = po;
+    }  else if (oid->len == 9) {
+    	/* XXX bounds check */
+    	po = &BRAINPOOL_oids[oid->data[8]];
+    	if(memcmp(oid->data, po->oid.data, 9) == 0) {
+    		ret = po;
+    	}
     }
     return(ret);
 }
