ec.c revision f4e427204234da139fd0585def4b4e22502e33f0
18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi/* Originally written by Bodo Moeller for the OpenSSL project. 28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ==================================================================== 38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Redistribution and use in source and binary forms, with or without 68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * modification, are permitted provided that the following conditions 78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * are met: 88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 1. Redistributions of source code must retain the above copyright 108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * notice, this list of conditions and the following disclaimer. 118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 2. Redistributions in binary form must reproduce the above copyright 138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * notice, this list of conditions and the following disclaimer in 148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * the documentation and/or other materials provided with the 158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * distribution. 168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 3. All advertising materials mentioning features or use of this 188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * software must display the following acknowledgment: 198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * "This product includes software developed by the OpenSSL Project 208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * endorse or promote products derived from this software without 248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * prior written permission. For written permission, please contact 258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * openssl-core@openssl.org. 268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 5. Products derived from this software may not be called "OpenSSL" 288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * nor may "OpenSSL" appear in their names without prior written 298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * permission of the OpenSSL Project. 308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 6. Redistributions of any form whatsoever must retain the following 328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * acknowledgment: 338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * "This product includes software developed by the OpenSSL Project 348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * OF THE POSSIBILITY OF SUCH DAMAGE. 488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ==================================================================== 498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * This product includes cryptographic software written by Eric Young 518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * (eay@cryptsoft.com). This product includes software written by Tim 528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Hudson (tjh@cryptsoft.com). 538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi */ 558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi/* ==================================================================== 568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Portions of the attached software ("Contribution") are developed by 598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * The Contribution is licensed pursuant to the OpenSSL open source 628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * license provided above. 638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * The elliptic curve binary polynomial software is originally written by 658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems 668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Laboratories. */ 678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/ec.h> 698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <string.h> 718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/bn.h> 738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/err.h> 748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/mem.h> 758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/obj.h> 768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include "internal.h" 788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P224 = { 818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "NIST P-224", 828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 28, 838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1, 848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi {/* p */ 858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x00, 0x00, 0x00, 0x01, 888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* a */ 898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFE, 928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* b */ 938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, 948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x23, 0x55, 0xFF, 0xB4, 968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* x */ 978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, 988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x11, 0x5C, 0x1D, 0x21, 1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* y */ 1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x85, 0x00, 0x7e, 0x34, 1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* order */ 1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x5C, 0x5C, 0x2A, 0x3D, 1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi }}; 1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P256 = { 1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "NIST P-256", 1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 32, 1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1, 1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi {/* p */ 1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* a */ 1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* b */ 1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, 1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* x */ 1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, 1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* y */ 1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, 1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* order */ 1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}}; 1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P384 = { 1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "NIST P-384", 1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 48, 1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1, 1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi {/* p */ 1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* a */ 1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* b */ 1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, 1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi /* x */ 1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, 163 /* y */ 164 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 165 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 166 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 167 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, 168 /* order */ 169 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 170 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 171 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 172 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}}; 173 174static const struct curve_data P521 = { 175 "NIST P-521", 176 66, 177 1, 178 {/* p */ 179 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 182 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 184 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 185 /* a */ 186 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 187 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 188 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 190 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 191 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 192 /* b */ 193 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 194 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 195 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 196 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 197 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 198 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, 199 /* x */ 200 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 201 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 202 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 203 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 204 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 205 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, 206 /* y */ 207 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 208 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 209 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 210 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 211 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 212 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 213 /* order */ 214 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 215 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 216 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 217 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 218 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 219 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}}; 220 221const struct built_in_curve OPENSSL_built_in_curves[] = { 222 {NID_secp224r1, &P224, 0}, 223 { 224 NID_X9_62_prime256v1, &P256, 225#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) 226 EC_GFp_nistp256_method, 227#else 228 0, 229#endif 230 }, 231 {NID_secp384r1, &P384, 0}, 232 {NID_secp521r1, &P521, 0}, 233 {NID_undef, 0, 0}, 234}; 235 236EC_GROUP *ec_group_new(const EC_METHOD *meth) { 237 EC_GROUP *ret; 238 239 if (meth == NULL) { 240 OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL); 241 return NULL; 242 } 243 244 if (meth->group_init == 0) { 245 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 246 return NULL; 247 } 248 249 ret = OPENSSL_malloc(sizeof(EC_GROUP)); 250 if (ret == NULL) { 251 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE); 252 return NULL; 253 } 254 memset(ret, 0, sizeof(EC_GROUP)); 255 256 ret->meth = meth; 257 BN_init(&ret->order); 258 BN_init(&ret->cofactor); 259 260 if (!meth->group_init(ret)) { 261 OPENSSL_free(ret); 262 return NULL; 263 } 264 265 return ret; 266} 267 268EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, 269 const BIGNUM *b, BN_CTX *ctx) { 270 const EC_METHOD *meth = EC_GFp_mont_method(); 271 EC_GROUP *ret; 272 273 ret = ec_group_new(meth); 274 if (ret == NULL) { 275 return NULL; 276 } 277 278 if (ret->meth->group_set_curve == 0) { 279 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp, 280 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 281 return 0; 282 } 283 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { 284 EC_GROUP_free(ret); 285 return NULL; 286 } 287 return ret; 288} 289 290int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 291 const BIGNUM *order, const BIGNUM *cofactor) { 292 if (group->curve_name != NID_undef) { 293 /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned 294 * by |EC_GROUP_new_curve_GFp|. */ 295 return 0; 296 } 297 298 if (group->generator == NULL) { 299 group->generator = EC_POINT_new(group); 300 if (group->generator == NULL) { 301 return 0; 302 } 303 } 304 305 if (!EC_POINT_copy(group->generator, generator)) { 306 return 0; 307 } 308 309 if (order != NULL) { 310 if (!BN_copy(&group->order, order)) { 311 return 0; 312 } 313 } else { 314 BN_zero(&group->order); 315 } 316 317 if (cofactor != NULL) { 318 if (!BN_copy(&group->cofactor, cofactor)) { 319 return 0; 320 } 321 } else { 322 BN_zero(&group->cofactor); 323 } 324 325 return 1; 326} 327 328static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { 329 EC_GROUP *group = NULL; 330 EC_POINT *P = NULL; 331 BN_CTX *ctx = NULL; 332 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL; 333 int ok = 0; 334 unsigned param_len; 335 const EC_METHOD *meth; 336 const struct curve_data *data; 337 const uint8_t *params; 338 339 if ((ctx = BN_CTX_new()) == NULL) { 340 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE); 341 goto err; 342 } 343 344 data = curve->data; 345 param_len = data->param_len; 346 params = data->data; 347 348 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || 349 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || 350 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { 351 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 352 goto err; 353 } 354 355 if (curve->method != 0) { 356 meth = curve->method(); 357 if (((group = ec_group_new(meth)) == NULL) || 358 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { 359 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 360 goto err; 361 } 362 } else { 363 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { 364 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 365 goto err; 366 } 367 } 368 369 if ((P = EC_POINT_new(group)) == NULL) { 370 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 371 goto err; 372 } 373 374 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) || 375 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { 376 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 377 goto err; 378 } 379 380 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { 381 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 382 goto err; 383 } 384 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) || 385 !BN_set_word(x, (BN_ULONG)data->cofactor)) { 386 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 387 goto err; 388 } 389 390 group->generator = P; 391 P = NULL; 392 if (!BN_copy(&group->order, order) || 393 !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) { 394 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 395 goto err; 396 } 397 398 ok = 1; 399 400err: 401 if (!ok) { 402 EC_GROUP_free(group); 403 group = NULL; 404 } 405 EC_POINT_free(P); 406 BN_CTX_free(ctx); 407 BN_free(p); 408 BN_free(a); 409 BN_free(b); 410 BN_free(order); 411 BN_free(x); 412 BN_free(y); 413 return group; 414} 415 416EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { 417 unsigned i; 418 const struct built_in_curve *curve; 419 EC_GROUP *ret = NULL; 420 421 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) { 422 curve = &OPENSSL_built_in_curves[i]; 423 if (curve->nid == nid) { 424 ret = ec_group_new_from_data(curve); 425 break; 426 } 427 } 428 429 if (ret == NULL) { 430 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP); 431 return NULL; 432 } 433 434 ret->curve_name = nid; 435 return ret; 436} 437 438void EC_GROUP_free(EC_GROUP *group) { 439 if (!group) { 440 return; 441 } 442 443 if (group->meth->group_finish != 0) { 444 group->meth->group_finish(group); 445 } 446 447 ec_pre_comp_free(group->pre_comp); 448 449 EC_POINT_free(group->generator); 450 BN_free(&group->order); 451 BN_free(&group->cofactor); 452 453 OPENSSL_free(group); 454} 455 456int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) { 457 if (dest->meth->group_copy == 0) { 458 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 459 return 0; 460 } 461 if (dest->meth != src->meth) { 462 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS); 463 return 0; 464 } 465 if (dest == src) { 466 return 1; 467 } 468 469 ec_pre_comp_free(dest->pre_comp); 470 dest->pre_comp = ec_pre_comp_dup(src->pre_comp); 471 472 if (src->generator != NULL) { 473 if (dest->generator == NULL) { 474 dest->generator = EC_POINT_new(dest); 475 if (dest->generator == NULL) { 476 return 0; 477 } 478 } 479 if (!EC_POINT_copy(dest->generator, src->generator)) { 480 return 0; 481 } 482 } else { 483 /* src->generator == NULL */ 484 if (dest->generator != NULL) { 485 EC_POINT_clear_free(dest->generator); 486 dest->generator = NULL; 487 } 488 } 489 490 if (!BN_copy(&dest->order, &src->order) || 491 !BN_copy(&dest->cofactor, &src->cofactor)) { 492 return 0; 493 } 494 495 dest->curve_name = src->curve_name; 496 497 return dest->meth->group_copy(dest, src); 498} 499 500EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { 501 EC_GROUP *t = NULL; 502 int ok = 0; 503 504 if (a == NULL) { 505 return NULL; 506 } 507 508 t = ec_group_new(a->meth); 509 if (t == NULL) { 510 return NULL; 511 } 512 if (!ec_group_copy(t, a)) { 513 goto err; 514 } 515 516 ok = 1; 517 518err: 519 if (!ok) { 520 EC_GROUP_free(t); 521 return NULL; 522 } else { 523 return t; 524 } 525} 526 527int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { 528 return a->curve_name == NID_undef || 529 b->curve_name == NID_undef || 530 a->curve_name != b->curve_name; 531} 532 533const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { 534 return group->generator; 535} 536 537int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { 538 if (!BN_copy(order, &group->order)) { 539 return 0; 540 } 541 542 return !BN_is_zero(order); 543} 544 545int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 546 BN_CTX *ctx) { 547 if (!BN_copy(cofactor, &group->cofactor)) { 548 return 0; 549 } 550 551 return !BN_is_zero(&group->cofactor); 552} 553 554int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, 555 BIGNUM *out_b, BN_CTX *ctx) { 556 if (group->meth->group_get_curve == 0) { 557 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp, 558 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 559 return 0; 560 } 561 return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx); 562} 563 564int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } 565 566int EC_GROUP_get_degree(const EC_GROUP *group) { 567 if (group->meth->group_get_degree == 0) { 568 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree, 569 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 570 return 0; 571 } 572 return group->meth->group_get_degree(group); 573} 574 575int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { 576 if (group->meth->mul == 0) { 577 /* use default */ 578 return ec_wNAF_precompute_mult(group, ctx); 579 } 580 581 if (group->meth->precompute_mult != 0) { 582 return group->meth->precompute_mult(group, ctx); 583 } 584 585 return 1; /* nothing to do, so report success */ 586} 587 588int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { 589 if (group->meth->mul == 0) { 590 /* use default */ 591 return ec_wNAF_have_precompute_mult(group); 592 } 593 594 if (group->meth->have_precompute_mult != 0) { 595 return group->meth->have_precompute_mult(group); 596 } 597 598 return 0; /* cannot tell whether precomputation has been performed */ 599} 600 601EC_POINT *EC_POINT_new(const EC_GROUP *group) { 602 EC_POINT *ret; 603 604 if (group == NULL) { 605 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER); 606 return NULL; 607 } 608 if (group->meth->point_init == 0) { 609 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 610 return NULL; 611 } 612 613 ret = OPENSSL_malloc(sizeof *ret); 614 if (ret == NULL) { 615 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE); 616 return NULL; 617 } 618 619 ret->meth = group->meth; 620 621 if (!ret->meth->point_init(ret)) { 622 OPENSSL_free(ret); 623 return NULL; 624 } 625 626 return ret; 627} 628 629void EC_POINT_free(EC_POINT *point) { 630 if (!point) { 631 return; 632 } 633 634 if (point->meth->point_finish != 0) { 635 point->meth->point_finish(point); 636 } 637 OPENSSL_free(point); 638} 639 640void EC_POINT_clear_free(EC_POINT *point) { 641 if (!point) { 642 return; 643 } 644 645 if (point->meth->point_clear_finish != 0) { 646 point->meth->point_clear_finish(point); 647 } else if (point->meth->point_finish != 0) { 648 point->meth->point_finish(point); 649 } 650 OPENSSL_cleanse(point, sizeof *point); 651 OPENSSL_free(point); 652} 653 654int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { 655 if (dest->meth->point_copy == 0) { 656 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 657 return 0; 658 } 659 if (dest->meth != src->meth) { 660 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS); 661 return 0; 662 } 663 if (dest == src) { 664 return 1; 665 } 666 return dest->meth->point_copy(dest, src); 667} 668 669EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { 670 EC_POINT *t; 671 int r; 672 673 if (a == NULL) { 674 return NULL; 675 } 676 677 t = EC_POINT_new(group); 678 if (t == NULL) { 679 OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE); 680 return NULL; 681 } 682 r = EC_POINT_copy(t, a); 683 if (!r) { 684 EC_POINT_free(t); 685 return NULL; 686 } else { 687 return t; 688 } 689} 690 691int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { 692 if (group->meth->point_set_to_infinity == 0) { 693 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, 694 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 695 return 0; 696 } 697 if (group->meth != point->meth) { 698 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS); 699 return 0; 700 } 701 return group->meth->point_set_to_infinity(group, point); 702} 703 704int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { 705 if (group->meth->is_at_infinity == 0) { 706 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, 707 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 708 return 0; 709 } 710 if (group->meth != point->meth) { 711 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS); 712 return 0; 713 } 714 return group->meth->is_at_infinity(group, point); 715} 716 717int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 718 BN_CTX *ctx) { 719 if (group->meth->is_on_curve == 0) { 720 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, 721 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 722 return 0; 723 } 724 if (group->meth != point->meth) { 725 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS); 726 return 0; 727 } 728 return group->meth->is_on_curve(group, point, ctx); 729} 730 731int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 732 BN_CTX *ctx) { 733 if (group->meth->point_cmp == 0) { 734 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 735 return -1; 736 } 737 if ((group->meth != a->meth) || (a->meth != b->meth)) { 738 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS); 739 return -1; 740 } 741 return group->meth->point_cmp(group, a, b, ctx); 742} 743 744int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { 745 if (group->meth->make_affine == 0) { 746 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, 747 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 748 return 0; 749 } 750 if (group->meth != point->meth) { 751 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS); 752 return 0; 753 } 754 return group->meth->make_affine(group, point, ctx); 755} 756 757int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 758 BN_CTX *ctx) { 759 size_t i; 760 761 if (group->meth->points_make_affine == 0) { 762 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, 763 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 764 return 0; 765 } 766 for (i = 0; i < num; i++) { 767 if (group->meth != points[i]->meth) { 768 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS); 769 return 0; 770 } 771 } 772 return group->meth->points_make_affine(group, num, points, ctx); 773} 774 775int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 776 const EC_POINT *point, BIGNUM *x, 777 BIGNUM *y, BN_CTX *ctx) { 778 if (group->meth->point_get_affine_coordinates == 0) { 779 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp, 780 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 781 return 0; 782 } 783 if (group->meth != point->meth) { 784 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp, 785 EC_R_INCOMPATIBLE_OBJECTS); 786 return 0; 787 } 788 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 789} 790 791int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 792 const BIGNUM *x, const BIGNUM *y, 793 BN_CTX *ctx) { 794 if (group->meth->point_set_affine_coordinates == 0) { 795 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp, 796 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 797 return 0; 798 } 799 if (group->meth != point->meth) { 800 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp, 801 EC_R_INCOMPATIBLE_OBJECTS); 802 return 0; 803 } 804 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 805} 806 807int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 808 const EC_POINT *b, BN_CTX *ctx) { 809 if (group->meth->add == 0) { 810 OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 811 return 0; 812 } 813 if ((group->meth != r->meth) || (r->meth != a->meth) || 814 (a->meth != b->meth)) { 815 OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS); 816 return 0; 817 } 818 return group->meth->add(group, r, a, b, ctx); 819} 820 821 822int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 823 BN_CTX *ctx) { 824 if (group->meth->dbl == 0) { 825 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 826 return 0; 827 } 828 if ((group->meth != r->meth) || (r->meth != a->meth)) { 829 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS); 830 return 0; 831 } 832 return group->meth->dbl(group, r, a, ctx); 833} 834 835 836int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { 837 if (group->meth->invert == 0) { 838 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 839 return 0; 840 } 841 if (group->meth != a->meth) { 842 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS); 843 return 0; 844 } 845 return group->meth->invert(group, a, ctx); 846} 847 848int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 849 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { 850 /* just a convenient interface to EC_POINTs_mul() */ 851 852 const EC_POINT *points[1]; 853 const BIGNUM *scalars[1]; 854 855 points[0] = point; 856 scalars[0] = p_scalar; 857 858 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), 859 points, scalars, ctx); 860} 861 862int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 863 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], 864 BN_CTX *ctx) { 865 if (group->meth->mul == 0) { 866 /* use default. Warning, not constant-time. */ 867 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 868 } 869 870 return group->meth->mul(group, r, scalar, num, points, scalars, ctx); 871} 872 873int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 874 const BIGNUM *x, const BIGNUM *y, 875 const BIGNUM *z, BN_CTX *ctx) { 876 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { 877 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp, 878 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 879 return 0; 880 } 881 if (group->meth != point->meth) { 882 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp, 883 EC_R_INCOMPATIBLE_OBJECTS); 884 return 0; 885 } 886 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, 887 z, ctx); 888} 889 890void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} 891 892const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { 893 return NULL; 894} 895 896int EC_METHOD_get_field_type(const EC_METHOD *meth) { 897 return NID_X9_62_prime_field; 898} 899 900void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 901 point_conversion_form_t form) { 902 if (form != POINT_CONVERSION_UNCOMPRESSED) { 903 abort(); 904 } 905} 906