1/* 2 * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4 * 5 * Licensed under the OpenSSL license (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11#include <string.h> 12 13#include <openssl/err.h> 14#include <openssl/opensslv.h> 15 16#include "ec_local.h" 17 18int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 19 const BIGNUM *x, int y_bit, BN_CTX *ctx) 20{ 21 if (group->meth->point_set_compressed_coordinates == NULL 22 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 23 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 24 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 25 return 0; 26 } 27 if (!ec_point_is_compat(point, group)) { 28 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 29 EC_R_INCOMPATIBLE_OBJECTS); 30 return 0; 31 } 32 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 33 if (group->meth->field_type == NID_X9_62_prime_field) 34 return ec_GFp_simple_set_compressed_coordinates(group, point, x, 35 y_bit, ctx); 36 else 37#ifdef OPENSSL_NO_EC2M 38 { 39 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 40 EC_R_GF2M_NOT_SUPPORTED); 41 return 0; 42 } 43#else 44 return ec_GF2m_simple_set_compressed_coordinates(group, point, x, 45 y_bit, ctx); 46#endif 47 } 48 return group->meth->point_set_compressed_coordinates(group, point, x, 49 y_bit, ctx); 50} 51 52#if OPENSSL_API_COMPAT < 0x10200000L 53int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, 54 EC_POINT *point, const BIGNUM *x, 55 int y_bit, BN_CTX *ctx) 56{ 57 return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx); 58} 59 60# ifndef OPENSSL_NO_EC2M 61int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, 62 EC_POINT *point, const BIGNUM *x, 63 int y_bit, BN_CTX *ctx) 64{ 65 return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx); 66} 67# endif 68#endif 69 70size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, 71 point_conversion_form_t form, unsigned char *buf, 72 size_t len, BN_CTX *ctx) 73{ 74 if (group->meth->point2oct == 0 75 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 76 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 77 return 0; 78 } 79 if (!ec_point_is_compat(point, group)) { 80 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); 81 return 0; 82 } 83 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 84 if (group->meth->field_type == NID_X9_62_prime_field) 85 return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); 86 else 87#ifdef OPENSSL_NO_EC2M 88 { 89 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); 90 return 0; 91 } 92#else 93 return ec_GF2m_simple_point2oct(group, point, 94 form, buf, len, ctx); 95#endif 96 } 97 98 return group->meth->point2oct(group, point, form, buf, len, ctx); 99} 100 101int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 102 const unsigned char *buf, size_t len, BN_CTX *ctx) 103{ 104 if (group->meth->oct2point == 0 105 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 106 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 107 return 0; 108 } 109 if (!ec_point_is_compat(point, group)) { 110 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); 111 return 0; 112 } 113 if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 114 if (group->meth->field_type == NID_X9_62_prime_field) 115 return ec_GFp_simple_oct2point(group, point, buf, len, ctx); 116 else 117#ifdef OPENSSL_NO_EC2M 118 { 119 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); 120 return 0; 121 } 122#else 123 return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); 124#endif 125 } 126 return group->meth->oct2point(group, point, buf, len, ctx); 127} 128 129size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, 130 point_conversion_form_t form, 131 unsigned char **pbuf, BN_CTX *ctx) 132{ 133 size_t len; 134 unsigned char *buf; 135 136 len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL); 137 if (len == 0) 138 return 0; 139 if ((buf = OPENSSL_malloc(len)) == NULL) { 140 ECerr(EC_F_EC_POINT_POINT2BUF, ERR_R_MALLOC_FAILURE); 141 return 0; 142 } 143 len = EC_POINT_point2oct(group, point, form, buf, len, ctx); 144 if (len == 0) { 145 OPENSSL_free(buf); 146 return 0; 147 } 148 *pbuf = buf; 149 return len; 150} 151