/* * Copyright (C) 2017 - This file is part of libecc project * * Authors: * Ryad BENADJILA * Arnaud EBALARD * Jean-Pierre FLORI * * Contributors: * Nicolas VIVET * Karim KHALFALLAH * * This software is licensed under a dual BSD and GPL v2 license. * See LICENSE file at the root folder of the project. */ #include /* * From a null-terminated string 'ec_name' of exact length 'ec_name_len' * (including final null character), the function returns a pointer * to the parameters for that curve via 'ec_params'. The function returns * -1 on error or if the search was unsuccessful. It returns 0 on success. * 'ec_params' is not meaningful on error. */ int ec_get_curve_params_by_name(const u8 *ec_name, u8 ec_name_len, const ec_str_params **ec_s_params) { const ec_str_params *params; u8 comp_len, name_len; u32 len; const ec_mapping *map; const u8 *name; unsigned int i; int ret, check; MUST_HAVE((ec_name != NULL), ret, err); MUST_HAVE((ec_s_params != NULL), ret, err); MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); /* * User has been warned ec_name_len is expected to include final * null character. */ ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err); comp_len = (u8)len; MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err); /* Iterate on our list of curves */ ret = -1; for (i = 0; i < EC_CURVES_NUM; i++) { map = &ec_maps[i]; params = map->params; MUST_HAVE((params != NULL), ret, err); MUST_HAVE((params->name != NULL), ret, err); MUST_HAVE((params->name->buf != NULL), ret, err); name = params->name->buf; name_len = params->name->buflen; if (name_len != ec_name_len) { continue; } if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) { (*ec_s_params) = params; ret = 0; break; } } err: return ret; } /* * From given curve type 'ec_type', the function provides a pointer to the * parameters for that curve if it is known, using 'ec_params' out parameter. * On error, or if the curve is unknown, the function returns -1, in which * case 'ec_params' is not meaningful. The function returns 0 on success. */ int ec_get_curve_params_by_type(ec_curve_type ec_type, const ec_str_params **ec_s_params) { const ec_str_params *params; const ec_mapping *map; const u8 *name; u32 len; u8 name_len; unsigned int i; int ret; MUST_HAVE((ec_s_params != NULL), ret, err); ret = -1; for (i = 0; i < EC_CURVES_NUM; i++) { map = &ec_maps[i]; params = map->params; MUST_HAVE((params != NULL), ret, err); if (ec_type == map->type) { /* Do some sanity check before returning */ MUST_HAVE((params->name != NULL), ret, err); MUST_HAVE((params->name->buf != NULL), ret, err); name = params->name->buf; ret = local_strlen((const char *)name, &len); EG(ret, err); MUST_HAVE(len < 256, ret, err); name_len = (u8)len; MUST_HAVE((params->name->buflen == (name_len + 1)), ret, err); (*ec_s_params) = params; ret = 0; break; } } err: return ret; } /* * From a null-terminated string 'ec_name' of exact length 'ec_name_len' * (including final null character), the function returns the curve type * via 'ec_type'. The function returns -1 on error or if the search was * unsuccessful. It returns 0 on success. 'ec_types' is not meaningful * on error. */ int ec_get_curve_type_by_name(const u8 *ec_name, u8 ec_name_len, ec_curve_type *ec_type) { const ec_str_params *params; u32 len; u8 name_len, comp_len; const ec_mapping *map; const u8 *name; unsigned int i; int ret, check; /* No need to bother w/ obvious crap */ MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); MUST_HAVE((ec_type != NULL), ret, err); MUST_HAVE((ec_name != NULL), ret, err); /* * User has been warned ec_name_len is expected to include final * null character. */ ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err); MUST_HAVE(len < 256, ret, err); comp_len = (u8)len; MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err); /* Iterate on our list of curves */ ret = -1; for (i = 0; i < EC_CURVES_NUM; i++) { map = &ec_maps[i]; params = map->params; MUST_HAVE((params != NULL), ret, err); MUST_HAVE((params->name != NULL), ret, err); MUST_HAVE((params->name->buf != NULL), ret, err); name = params->name->buf; name_len = params->name->buflen; if (name_len != ec_name_len) { continue; } if((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) { (*ec_type) = map->type; ret = 0; break; } } err: return ret; } /* * Given a curve type, the function finds the curve described by given type * and write its name (null terminated string) to given output buffer 'out' * of length 'outlen'. 0 is returned on success, -1 otherwise. */ int ec_get_curve_name_by_type(const ec_curve_type ec_type, u8 *out, u8 outlen) { const ec_str_params *by_type; const u8 *name; u8 name_len; int ret; MUST_HAVE((out != NULL), ret, err); /* Let's first do the lookup by type */ ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err); /* Found a curve for that type. Let's check name matches. */ MUST_HAVE((by_type != NULL), ret, err); MUST_HAVE((by_type->name != NULL), ret, err); MUST_HAVE((by_type->name->buf != NULL), ret, err); name_len = by_type->name->buflen; name = by_type->name->buf; /* Not enough room to copy curve name? */ MUST_HAVE((name_len <= outlen), ret, err); ret = local_memcpy(out, name, name_len); err: return ret; } /* * The function verifies the coherency between given curve type value and * associated name 'ec_name' of length 'ec_name_len' (including final * null character). The function returns 0 if the curve type is known * and provided name matches expected one. The function returns -1 * otherwise. */ int ec_check_curve_type_and_name(const ec_curve_type ec_type, const u8 *ec_name, u8 ec_name_len) { const ec_str_params *by_type; const u8 *name; u8 name_len; int ret, check; /* No need to bother w/ obvious crap */ MUST_HAVE((ec_name != NULL), ret, err); MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); /* Let's first do the lookup by type */ ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err); /* Found a curve for that type. Let's check name matches. */ MUST_HAVE((by_type != NULL), ret, err); MUST_HAVE((by_type->name != NULL), ret, err); MUST_HAVE((by_type->name->buf != NULL), ret, err); name = by_type->name->buf; name_len = by_type->name->buflen; MUST_HAVE((name_len == ec_name_len), ret, err); if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && (!check)) { ret = -1; } err: return ret; }