ec_oct.c revision 1.6
1/* $OpenBSD: ec_oct.c,v 1.6 2020/12/04 08:55:30 tb Exp $ */ 2/* 3 * Originally written by Bodo Moeller for the OpenSSL project. 4 */ 5/* ==================================================================== 6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * openssl-core@openssl.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58/* ==================================================================== 59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60 * Binary polynomial ECC support in OpenSSL originally developed by 61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 62 */ 63 64#include <string.h> 65 66#include <openssl/opensslconf.h> 67 68#include <openssl/err.h> 69#include <openssl/opensslv.h> 70 71#include "ec_lcl.h" 72 73int 74EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP * group, EC_POINT * point, 75 const BIGNUM * x, int y_bit, BN_CTX * ctx) 76{ 77 if (group->meth->point_set_compressed_coordinates == 0 78 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 79 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 80 return 0; 81 } 82 if (group->meth != point->meth) { 83 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 84 return 0; 85 } 86 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 87 if (group->meth->field_type == NID_X9_62_prime_field) 88 return ec_GFp_simple_set_compressed_coordinates( 89 group, point, x, y_bit, ctx); 90 else 91#ifdef OPENSSL_NO_EC2M 92 { 93 ECerror(EC_R_GF2M_NOT_SUPPORTED); 94 return 0; 95 } 96#else 97 return ec_GF2m_simple_set_compressed_coordinates( 98 group, point, x, y_bit, ctx); 99#endif 100 } 101 if (!group->meth->point_set_compressed_coordinates(group, point, x, 102 y_bit, ctx)) 103 return 0; 104 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 105 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 106 return 0; 107 } 108 return 1; 109} 110 111#ifndef OPENSSL_NO_EC2M 112int 113EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP * group, EC_POINT * point, 114 const BIGNUM * x, int y_bit, BN_CTX * ctx) 115{ 116 if (group->meth->point_set_compressed_coordinates == 0 117 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 118 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 119 return 0; 120 } 121 if (group->meth != point->meth) { 122 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 123 return 0; 124 } 125 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 126 if (group->meth->field_type == NID_X9_62_prime_field) 127 return ec_GFp_simple_set_compressed_coordinates( 128 group, point, x, y_bit, ctx); 129 else 130 return ec_GF2m_simple_set_compressed_coordinates( 131 group, point, x, y_bit, ctx); 132 } 133 if (!group->meth->point_set_compressed_coordinates(group, point, x, 134 y_bit, ctx)) 135 return 0; 136 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 137 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 138 return 0; 139 } 140 return 1; 141} 142#endif 143 144size_t 145EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, 146 point_conversion_form_t form, 147 unsigned char *buf, size_t len, BN_CTX *ctx) 148{ 149 if (group->meth->point2oct == 0 150 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 151 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 152 return 0; 153 } 154 if (group->meth != point->meth) { 155 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 156 return 0; 157 } 158 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 159 if (group->meth->field_type == NID_X9_62_prime_field) 160 return ec_GFp_simple_point2oct(group, point, 161 form, buf, len, ctx); 162 else 163#ifdef OPENSSL_NO_EC2M 164 { 165 ECerror(EC_R_GF2M_NOT_SUPPORTED); 166 return 0; 167 } 168#else 169 return ec_GF2m_simple_point2oct(group, point, 170 form, buf, len, ctx); 171#endif 172 } 173 return group->meth->point2oct(group, point, form, buf, len, ctx); 174} 175 176 177int 178EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 179 const unsigned char *buf, size_t len, BN_CTX *ctx) 180{ 181 if (group->meth->oct2point == 0 && 182 !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 183 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 184 return 0; 185 } 186 if (group->meth != point->meth) { 187 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 188 return 0; 189 } 190 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 191 if (group->meth->field_type == NID_X9_62_prime_field) 192 return ec_GFp_simple_oct2point(group, point, 193 buf, len, ctx); 194 else 195#ifdef OPENSSL_NO_EC2M 196 { 197 ECerror(EC_R_GF2M_NOT_SUPPORTED); 198 return 0; 199 } 200#else 201 return ec_GF2m_simple_oct2point(group, point, 202 buf, len, ctx); 203#endif 204 } 205 return group->meth->oct2point(group, point, buf, len, ctx); 206} 207