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