Path: blob/main/crypto/libecc/src/curves/curves.c
105295 views
/*1* Copyright (C) 2017 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6* Jean-Pierre FLORI <[email protected]>7*8* Contributors:9* Nicolas VIVET <[email protected]>10* Karim KHALFALLAH <[email protected]>11*12* This software is licensed under a dual BSD and GPL v2 license.13* See LICENSE file at the root folder of the project.14*/15#include <libecc/curves/curves.h>1617/*18* From a null-terminated string 'ec_name' of exact length 'ec_name_len'19* (including final null character), the function returns a pointer20* to the parameters for that curve via 'ec_params'. The function returns21* -1 on error or if the search was unsuccessful. It returns 0 on success.22* 'ec_params' is not meaningful on error.23*/24int ec_get_curve_params_by_name(const u8 *ec_name, u8 ec_name_len,25const ec_str_params **ec_s_params)26{27const ec_str_params *params;28u8 comp_len, name_len;29u32 len;30const ec_mapping *map;31const u8 *name;32unsigned int i;33int ret, check;3435MUST_HAVE((ec_name != NULL), ret, err);36MUST_HAVE((ec_s_params != NULL), ret, err);37MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err);3839/*40* User has been warned ec_name_len is expected to include final41* null character.42*/43ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err);44comp_len = (u8)len;45MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err);4647/* Iterate on our list of curves */48ret = -1;49for (i = 0; i < EC_CURVES_NUM; i++) {50map = &ec_maps[i];51params = map->params;5253MUST_HAVE((params != NULL), ret, err);54MUST_HAVE((params->name != NULL), ret, err);55MUST_HAVE((params->name->buf != NULL), ret, err);5657name = params->name->buf;58name_len = params->name->buflen;5960if (name_len != ec_name_len) {61continue;62}6364if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) {65(*ec_s_params) = params;66ret = 0;67break;68}69}7071err:72return ret;73}7475/*76* From given curve type 'ec_type', the function provides a pointer to the77* parameters for that curve if it is known, using 'ec_params' out parameter.78* On error, or if the curve is unknown, the function returns -1, in which79* case 'ec_params' is not meaningful. The function returns 0 on success.80*/81int ec_get_curve_params_by_type(ec_curve_type ec_type,82const ec_str_params **ec_s_params)83{84const ec_str_params *params;85const ec_mapping *map;86const u8 *name;87u32 len;88u8 name_len;89unsigned int i;90int ret;9192MUST_HAVE((ec_s_params != NULL), ret, err);9394ret = -1;95for (i = 0; i < EC_CURVES_NUM; i++) {96map = &ec_maps[i];97params = map->params;9899MUST_HAVE((params != NULL), ret, err);100101if (ec_type == map->type) {102/* Do some sanity check before returning */103MUST_HAVE((params->name != NULL), ret, err);104MUST_HAVE((params->name->buf != NULL), ret, err);105106name = params->name->buf;107ret = local_strlen((const char *)name, &len); EG(ret, err);108MUST_HAVE(len < 256, ret, err);109name_len = (u8)len;110111MUST_HAVE((params->name->buflen == (name_len + 1)), ret, err);112113(*ec_s_params) = params;114ret = 0;115break;116}117}118119err:120return ret;121}122123/*124* From a null-terminated string 'ec_name' of exact length 'ec_name_len'125* (including final null character), the function returns the curve type126* via 'ec_type'. The function returns -1 on error or if the search was127* unsuccessful. It returns 0 on success. 'ec_types' is not meaningful128* on error.129*/130int ec_get_curve_type_by_name(const u8 *ec_name, u8 ec_name_len,131ec_curve_type *ec_type)132{133const ec_str_params *params;134u32 len;135u8 name_len, comp_len;136const ec_mapping *map;137const u8 *name;138unsigned int i;139int ret, check;140141/* No need to bother w/ obvious crap */142MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err);143MUST_HAVE((ec_type != NULL), ret, err);144MUST_HAVE((ec_name != NULL), ret, err);145146/*147* User has been warned ec_name_len is expected to include final148* null character.149*/150ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err);151MUST_HAVE(len < 256, ret, err);152comp_len = (u8)len;153MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err);154155/* Iterate on our list of curves */156ret = -1;157for (i = 0; i < EC_CURVES_NUM; i++) {158map = &ec_maps[i];159params = map->params;160161MUST_HAVE((params != NULL), ret, err);162MUST_HAVE((params->name != NULL), ret, err);163MUST_HAVE((params->name->buf != NULL), ret, err);164165name = params->name->buf;166name_len = params->name->buflen;167168if (name_len != ec_name_len) {169continue;170}171172if((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) {173(*ec_type) = map->type;174ret = 0;175break;176}177}178179err:180return ret;181}182183/*184* Given a curve type, the function finds the curve described by given type185* and write its name (null terminated string) to given output buffer 'out'186* of length 'outlen'. 0 is returned on success, -1 otherwise.187*/188int ec_get_curve_name_by_type(const ec_curve_type ec_type, u8 *out, u8 outlen)189{190const ec_str_params *by_type;191const u8 *name;192u8 name_len;193int ret;194195MUST_HAVE((out != NULL), ret, err);196197/* Let's first do the lookup by type */198ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err);199200/* Found a curve for that type. Let's check name matches. */201MUST_HAVE((by_type != NULL), ret, err);202MUST_HAVE((by_type->name != NULL), ret, err);203MUST_HAVE((by_type->name->buf != NULL), ret, err);204205name_len = by_type->name->buflen;206name = by_type->name->buf;207208/* Not enough room to copy curve name? */209MUST_HAVE((name_len <= outlen), ret, err);210211ret = local_memcpy(out, name, name_len);212213err:214return ret;215}216217/*218* The function verifies the coherency between given curve type value and219* associated name 'ec_name' of length 'ec_name_len' (including final220* null character). The function returns 0 if the curve type is known221* and provided name matches expected one. The function returns -1222* otherwise.223*/224int ec_check_curve_type_and_name(const ec_curve_type ec_type,225const u8 *ec_name, u8 ec_name_len)226{227const ec_str_params *by_type;228const u8 *name;229u8 name_len;230int ret, check;231232/* No need to bother w/ obvious crap */233MUST_HAVE((ec_name != NULL), ret, err);234MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err);235236/* Let's first do the lookup by type */237ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err);238239/* Found a curve for that type. Let's check name matches. */240MUST_HAVE((by_type != NULL), ret, err);241MUST_HAVE((by_type->name != NULL), ret, err);242MUST_HAVE((by_type->name->buf != NULL), ret, err);243244name = by_type->name->buf;245name_len = by_type->name->buflen;246247MUST_HAVE((name_len == ec_name_len), ret, err);248249if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && (!check)) {250ret = -1;251}252253err:254return ret;255}256257258