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