Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/security/ec/impl/ecdecode.c
38918 views
/*1* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.2* Use is subject to license terms.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public6* License as published by the Free Software Foundation; either7* version 2.1 of the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public License15* along with this library; if not, write to the Free Software Foundation,16* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* *********************************************************************24*25* The Original Code is the Elliptic Curve Cryptography library.26*27* The Initial Developer of the Original Code is28* Sun Microsystems, Inc.29* Portions created by the Initial Developer are Copyright (C) 200330* the Initial Developer. All Rights Reserved.31*32* Contributor(s):33* Dr Vipul Gupta <[email protected]> and34* Douglas Stebila <[email protected]>, Sun Microsystems Laboratories35*36* Last Modified Date from the Original Code: March 201237*********************************************************************** */3839#include <sys/types.h>4041#ifndef _WIN3242#if !defined(__linux__) && !defined(_ALLBSD_SOURCE)43#include <sys/systm.h>44#endif /* __linux__ || _ALLBSD_SOURCE */45#include <sys/param.h>46#endif /* _WIN32 */4748#ifdef _KERNEL49#include <sys/kmem.h>50#else51#include <string.h>52#endif53#include "ec.h"54#include "ecl-curve.h"55#include "ecc_impl.h"5657#define MAX_ECKEY_LEN 7258#define SEC_ASN1_OBJECT_ID 0x065960/*61* Initializes a SECItem from a hexadecimal string62*63* Warning: This function ignores leading 00's, so any leading 00's64* in the hexadecimal string must be optional.65*/66static SECItem *67hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,68int kmflag)69{70int i = 0;71int byteval = 0;72int tmp = (int)strlen(str);7374if ((tmp % 2) != 0) return NULL;7576/* skip leading 00's unless the hex string is "00" */77while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {78str += 2;79tmp -= 2;80}8182item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);83if (item->data == NULL) return NULL;84item->len = tmp/2;8586while (str[i]) {87if ((str[i] >= '0') && (str[i] <= '9'))88tmp = str[i] - '0';89else if ((str[i] >= 'a') && (str[i] <= 'f'))90tmp = str[i] - 'a' + 10;91else if ((str[i] >= 'A') && (str[i] <= 'F'))92tmp = str[i] - 'A' + 10;93else94return NULL;9596byteval = byteval * 16 + tmp;97if ((i % 2) != 0) {98item->data[i/2] = byteval;99byteval = 0;100}101i++;102}103104return item;105}106107static SECStatus108gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,109int kmflag)110{111SECStatus rv = SECFailure;112const ECCurveParams *curveParams;113/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */114char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];115116if (((int)name < ECCurve_noName) || (name > ECCurve_pastLastCurve))117goto cleanup;118params->name = name;119curveParams = ecCurve_map[params->name];120CHECK_OK(curveParams);121params->fieldID.size = curveParams->size;122params->fieldID.type = field_type;123if (field_type == ec_field_GFp) {124CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime,125curveParams->irr, kmflag));126} else {127CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly,128curveParams->irr, kmflag));129}130CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a,131curveParams->curvea, kmflag));132CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b,133curveParams->curveb, kmflag));134genenc[0] = '0';135genenc[1] = '4';136genenc[2] = '\0';137strcat(genenc, curveParams->genx);138strcat(genenc, curveParams->geny);139CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag));140CHECK_OK(hexString2SECItem(NULL, ¶ms->order,141curveParams->order, kmflag));142params->cofactor = curveParams->cofactor;143144rv = SECSuccess;145146cleanup:147return rv;148}149150ECCurveName SECOID_FindOIDTag(const SECItem *);151152SECStatus153EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,154ECParams *params, int kmflag)155{156SECStatus rv = SECFailure;157ECCurveName tag;158SECItem oid = { siBuffer, NULL, 0};159160#if EC_DEBUG161int i;162163printf("Encoded params in EC_DecodeParams: ");164for (i = 0; i < encodedParams->len; i++) {165printf("%02x:", encodedParams->data[i]);166}167printf("\n");168#endif169170if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&171(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {172PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);173return SECFailure;174};175176oid.len = encodedParams->len - 2;177oid.data = encodedParams->data + 2;178if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||179((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {180PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);181return SECFailure;182}183184params->arena = arena;185params->cofactor = 0;186params->type = ec_params_named;187params->name = ECCurve_noName;188189/* For named curves, fill out curveOID */190params->curveOID.len = oid.len;191params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,192kmflag);193if (params->curveOID.data == NULL) goto cleanup;194memcpy(params->curveOID.data, oid.data, oid.len);195196#if EC_DEBUG197#ifndef SECOID_FindOIDTagDescription198printf("Curve: %s\n", ecCurve_map[tag]->text);199#else200printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));201#endif202#endif203204switch (tag) {205206/* Binary curves */207208case ECCurve_X9_62_CHAR2_PNB163V1:209/* Populate params for c2pnb163v1 */210CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,211params, kmflag) );212break;213214case ECCurve_X9_62_CHAR2_PNB163V2:215/* Populate params for c2pnb163v2 */216CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,217params, kmflag) );218break;219220case ECCurve_X9_62_CHAR2_PNB163V3:221/* Populate params for c2pnb163v3 */222CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,223params, kmflag) );224break;225226case ECCurve_X9_62_CHAR2_PNB176V1:227/* Populate params for c2pnb176v1 */228CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,229params, kmflag) );230break;231232case ECCurve_X9_62_CHAR2_TNB191V1:233/* Populate params for c2tnb191v1 */234CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,235params, kmflag) );236break;237238case ECCurve_X9_62_CHAR2_TNB191V2:239/* Populate params for c2tnb191v2 */240CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,241params, kmflag) );242break;243244case ECCurve_X9_62_CHAR2_TNB191V3:245/* Populate params for c2tnb191v3 */246CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,247params, kmflag) );248break;249250case ECCurve_X9_62_CHAR2_PNB208W1:251/* Populate params for c2pnb208w1 */252CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,253params, kmflag) );254break;255256case ECCurve_X9_62_CHAR2_TNB239V1:257/* Populate params for c2tnb239v1 */258CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,259params, kmflag) );260break;261262case ECCurve_X9_62_CHAR2_TNB239V2:263/* Populate params for c2tnb239v2 */264CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,265params, kmflag) );266break;267268case ECCurve_X9_62_CHAR2_TNB239V3:269/* Populate params for c2tnb239v3 */270CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,271params, kmflag) );272break;273274case ECCurve_X9_62_CHAR2_PNB272W1:275/* Populate params for c2pnb272w1 */276CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,277params, kmflag) );278break;279280case ECCurve_X9_62_CHAR2_PNB304W1:281/* Populate params for c2pnb304w1 */282CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,283params, kmflag) );284break;285286case ECCurve_X9_62_CHAR2_TNB359V1:287/* Populate params for c2tnb359v1 */288CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,289params, kmflag) );290break;291292case ECCurve_X9_62_CHAR2_PNB368W1:293/* Populate params for c2pnb368w1 */294CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,295params, kmflag) );296break;297298case ECCurve_X9_62_CHAR2_TNB431R1:299/* Populate params for c2tnb431r1 */300CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,301params, kmflag) );302break;303304case ECCurve_SECG_CHAR2_113R1:305/* Populate params for sect113r1 */306CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,307params, kmflag) );308break;309310case ECCurve_SECG_CHAR2_113R2:311/* Populate params for sect113r2 */312CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,313params, kmflag) );314break;315316case ECCurve_SECG_CHAR2_131R1:317/* Populate params for sect131r1 */318CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,319params, kmflag) );320break;321322case ECCurve_SECG_CHAR2_131R2:323/* Populate params for sect131r2 */324CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,325params, kmflag) );326break;327328case ECCurve_SECG_CHAR2_163K1:329/* Populate params for sect163k1330* (the NIST K-163 curve)331*/332CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,333params, kmflag) );334break;335336case ECCurve_SECG_CHAR2_163R1:337/* Populate params for sect163r1 */338CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,339params, kmflag) );340break;341342case ECCurve_SECG_CHAR2_163R2:343/* Populate params for sect163r2344* (the NIST B-163 curve)345*/346CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,347params, kmflag) );348break;349350case ECCurve_SECG_CHAR2_193R1:351/* Populate params for sect193r1 */352CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,353params, kmflag) );354break;355356case ECCurve_SECG_CHAR2_193R2:357/* Populate params for sect193r2 */358CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,359params, kmflag) );360break;361362case ECCurve_SECG_CHAR2_233K1:363/* Populate params for sect233k1364* (the NIST K-233 curve)365*/366CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,367params, kmflag) );368break;369370case ECCurve_SECG_CHAR2_233R1:371/* Populate params for sect233r1372* (the NIST B-233 curve)373*/374CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,375params, kmflag) );376break;377378case ECCurve_SECG_CHAR2_239K1:379/* Populate params for sect239k1 */380CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,381params, kmflag) );382break;383384case ECCurve_SECG_CHAR2_283K1:385/* Populate params for sect283k1386* (the NIST K-283 curve)387*/388CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,389params, kmflag) );390break;391392case ECCurve_SECG_CHAR2_283R1:393/* Populate params for sect283r1394* (the NIST B-283 curve)395*/396CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,397params, kmflag) );398break;399400case ECCurve_SECG_CHAR2_409K1:401/* Populate params for sect409k1402* (the NIST K-409 curve)403*/404CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,405params, kmflag) );406break;407408case ECCurve_SECG_CHAR2_409R1:409/* Populate params for sect409r1410* (the NIST B-409 curve)411*/412CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,413params, kmflag) );414break;415416case ECCurve_SECG_CHAR2_571K1:417/* Populate params for sect571k1418* (the NIST K-571 curve)419*/420CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,421params, kmflag) );422break;423424case ECCurve_SECG_CHAR2_571R1:425/* Populate params for sect571r1426* (the NIST B-571 curve)427*/428CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,429params, kmflag) );430break;431432/* Prime curves */433434case ECCurve_X9_62_PRIME_192V1:435/* Populate params for prime192v1 aka secp192r1436* (the NIST P-192 curve)437*/438CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,439params, kmflag) );440break;441442case ECCurve_X9_62_PRIME_192V2:443/* Populate params for prime192v2 */444CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,445params, kmflag) );446break;447448case ECCurve_X9_62_PRIME_192V3:449/* Populate params for prime192v3 */450CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,451params, kmflag) );452break;453454case ECCurve_X9_62_PRIME_239V1:455/* Populate params for prime239v1 */456CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,457params, kmflag) );458break;459460case ECCurve_X9_62_PRIME_239V2:461/* Populate params for prime239v2 */462CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,463params, kmflag) );464break;465466case ECCurve_X9_62_PRIME_239V3:467/* Populate params for prime239v3 */468CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,469params, kmflag) );470break;471472case ECCurve_X9_62_PRIME_256V1:473/* Populate params for prime256v1 aka secp256r1474* (the NIST P-256 curve)475*/476CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,477params, kmflag) );478break;479480case ECCurve_SECG_PRIME_112R1:481/* Populate params for secp112r1 */482CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,483params, kmflag) );484break;485486case ECCurve_SECG_PRIME_112R2:487/* Populate params for secp112r2 */488CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,489params, kmflag) );490break;491492case ECCurve_SECG_PRIME_128R1:493/* Populate params for secp128r1 */494CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,495params, kmflag) );496break;497498case ECCurve_SECG_PRIME_128R2:499/* Populate params for secp128r2 */500CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,501params, kmflag) );502break;503504case ECCurve_SECG_PRIME_160K1:505/* Populate params for secp160k1 */506CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,507params, kmflag) );508break;509510case ECCurve_SECG_PRIME_160R1:511/* Populate params for secp160r1 */512CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,513params, kmflag) );514break;515516case ECCurve_SECG_PRIME_160R2:517/* Populate params for secp160r1 */518CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,519params, kmflag) );520break;521522case ECCurve_SECG_PRIME_192K1:523/* Populate params for secp192k1 */524CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,525params, kmflag) );526break;527528case ECCurve_SECG_PRIME_224K1:529/* Populate params for secp224k1 */530CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,531params, kmflag) );532break;533534case ECCurve_SECG_PRIME_224R1:535/* Populate params for secp224r1536* (the NIST P-224 curve)537*/538CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,539params, kmflag) );540break;541542case ECCurve_SECG_PRIME_256K1:543/* Populate params for secp256k1 */544CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,545params, kmflag) );546break;547548case ECCurve_SECG_PRIME_384R1:549/* Populate params for secp384r1550* (the NIST P-384 curve)551*/552CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,553params, kmflag) );554break;555556case ECCurve_SECG_PRIME_521R1:557/* Populate params for secp521r1558* (the NIST P-521 curve)559*/560CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,561params, kmflag) );562break;563564default:565break;566};567568cleanup:569if (!params->cofactor) {570PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);571#if EC_DEBUG572printf("Unrecognized curve, returning NULL params\n");573#endif574}575576return rv;577}578579SECStatus580EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)581{582PRArenaPool *arena;583ECParams *params;584SECStatus rv = SECFailure;585586/* Initialize an arena for the ECParams structure */587if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))588return SECFailure;589590params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);591if (!params) {592PORT_FreeArena(NULL, B_TRUE);593return SECFailure;594}595596/* Copy the encoded params */597SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,598kmflag);599memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);600601/* Fill out the rest of the ECParams structure based on602* the encoded params603*/604rv = EC_FillParams(NULL, encodedParams, params, kmflag);605if (rv == SECFailure) {606PORT_FreeArena(NULL, B_TRUE);607return SECFailure;608} else {609*ecparams = params;;610return SECSuccess;611}612}613614615