1 /* 2 * Copyright (C) 2017 - This file is part of libecc project 3 * 4 * Authors: 5 * Ryad BENADJILA <ryadbenadjila@gmail.com> 6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8 * 9 * Contributors: 10 * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11 * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12 * 13 * This software is licensed under a dual BSD and GPL v2 license. 14 * See LICENSE file at the root folder of the project. 15 */ 16 #include <libecc/curves/curves.h> 17 18 /* 19 * From a null-terminated string 'ec_name' of exact length 'ec_name_len' 20 * (including final null character), the function returns a pointer 21 * to the parameters for that curve via 'ec_params'. The function returns 22 * -1 on error or if the search was unsuccessful. It returns 0 on success. 23 * 'ec_params' is not meaningful on error. 24 */ 25 int ec_get_curve_params_by_name(const u8 *ec_name, u8 ec_name_len, 26 const ec_str_params **ec_s_params) 27 { 28 const ec_str_params *params; 29 u8 comp_len, name_len; 30 u32 len; 31 const ec_mapping *map; 32 const u8 *name; 33 unsigned int i; 34 int ret, check; 35 36 MUST_HAVE((ec_name != NULL), ret, err); 37 MUST_HAVE((ec_s_params != NULL), ret, err); 38 MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); 39 40 /* 41 * User has been warned ec_name_len is expected to include final 42 * null character. 43 */ 44 ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err); 45 comp_len = (u8)len; 46 MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err); 47 48 /* Iterate on our list of curves */ 49 ret = -1; 50 for (i = 0; i < EC_CURVES_NUM; i++) { 51 map = &ec_maps[i]; 52 params = map->params; 53 54 MUST_HAVE((params != NULL), ret, err); 55 MUST_HAVE((params->name != NULL), ret, err); 56 MUST_HAVE((params->name->buf != NULL), ret, err); 57 58 name = params->name->buf; 59 name_len = params->name->buflen; 60 61 if (name_len != ec_name_len) { 62 continue; 63 } 64 65 if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) { 66 (*ec_s_params) = params; 67 ret = 0; 68 break; 69 } 70 } 71 72 err: 73 return ret; 74 } 75 76 /* 77 * From given curve type 'ec_type', the function provides a pointer to the 78 * parameters for that curve if it is known, using 'ec_params' out parameter. 79 * On error, or if the curve is unknown, the function returns -1, in which 80 * case 'ec_params' is not meaningful. The function returns 0 on success. 81 */ 82 int ec_get_curve_params_by_type(ec_curve_type ec_type, 83 const ec_str_params **ec_s_params) 84 { 85 const ec_str_params *params; 86 const ec_mapping *map; 87 const u8 *name; 88 u32 len; 89 u8 name_len; 90 unsigned int i; 91 int ret; 92 93 MUST_HAVE((ec_s_params != NULL), ret, err); 94 95 ret = -1; 96 for (i = 0; i < EC_CURVES_NUM; i++) { 97 map = &ec_maps[i]; 98 params = map->params; 99 100 MUST_HAVE((params != NULL), ret, err); 101 102 if (ec_type == map->type) { 103 /* Do some sanity check before returning */ 104 MUST_HAVE((params->name != NULL), ret, err); 105 MUST_HAVE((params->name->buf != NULL), ret, err); 106 107 name = params->name->buf; 108 ret = local_strlen((const char *)name, &len); EG(ret, err); 109 MUST_HAVE(len < 256, ret, err); 110 name_len = (u8)len; 111 112 MUST_HAVE((params->name->buflen == (name_len + 1)), ret, err); 113 114 (*ec_s_params) = params; 115 ret = 0; 116 break; 117 } 118 } 119 120 err: 121 return ret; 122 } 123 124 /* 125 * From a null-terminated string 'ec_name' of exact length 'ec_name_len' 126 * (including final null character), the function returns the curve type 127 * via 'ec_type'. The function returns -1 on error or if the search was 128 * unsuccessful. It returns 0 on success. 'ec_types' is not meaningful 129 * on error. 130 */ 131 int ec_get_curve_type_by_name(const u8 *ec_name, u8 ec_name_len, 132 ec_curve_type *ec_type) 133 { 134 const ec_str_params *params; 135 u32 len; 136 u8 name_len, comp_len; 137 const ec_mapping *map; 138 const u8 *name; 139 unsigned int i; 140 int ret, check; 141 142 /* No need to bother w/ obvious crap */ 143 MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); 144 MUST_HAVE((ec_type != NULL), ret, err); 145 MUST_HAVE((ec_name != NULL), ret, err); 146 147 /* 148 * User has been warned ec_name_len is expected to include final 149 * null character. 150 */ 151 ret = local_strnlen((const char *)ec_name, ec_name_len, &len); EG(ret, err); 152 MUST_HAVE(len < 256, ret, err); 153 comp_len = (u8)len; 154 MUST_HAVE(((comp_len + 1) == ec_name_len), ret, err); 155 156 /* Iterate on our list of curves */ 157 ret = -1; 158 for (i = 0; i < EC_CURVES_NUM; i++) { 159 map = &ec_maps[i]; 160 params = map->params; 161 162 MUST_HAVE((params != NULL), ret, err); 163 MUST_HAVE((params->name != NULL), ret, err); 164 MUST_HAVE((params->name->buf != NULL), ret, err); 165 166 name = params->name->buf; 167 name_len = params->name->buflen; 168 169 if (name_len != ec_name_len) { 170 continue; 171 } 172 173 if((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && check) { 174 (*ec_type) = map->type; 175 ret = 0; 176 break; 177 } 178 } 179 180 err: 181 return ret; 182 } 183 184 /* 185 * Given a curve type, the function finds the curve described by given type 186 * and write its name (null terminated string) to given output buffer 'out' 187 * of length 'outlen'. 0 is returned on success, -1 otherwise. 188 */ 189 int ec_get_curve_name_by_type(const ec_curve_type ec_type, u8 *out, u8 outlen) 190 { 191 const ec_str_params *by_type; 192 const u8 *name; 193 u8 name_len; 194 int ret; 195 196 MUST_HAVE((out != NULL), ret, err); 197 198 /* Let's first do the lookup by type */ 199 ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err); 200 201 /* Found a curve for that type. Let's check name matches. */ 202 MUST_HAVE((by_type != NULL), ret, err); 203 MUST_HAVE((by_type->name != NULL), ret, err); 204 MUST_HAVE((by_type->name->buf != NULL), ret, err); 205 206 name_len = by_type->name->buflen; 207 name = by_type->name->buf; 208 209 /* Not enough room to copy curve name? */ 210 MUST_HAVE((name_len <= outlen), ret, err); 211 212 ret = local_memcpy(out, name, name_len); 213 214 err: 215 return ret; 216 } 217 218 /* 219 * The function verifies the coherency between given curve type value and 220 * associated name 'ec_name' of length 'ec_name_len' (including final 221 * null character). The function returns 0 if the curve type is known 222 * and provided name matches expected one. The function returns -1 223 * otherwise. 224 */ 225 int ec_check_curve_type_and_name(const ec_curve_type ec_type, 226 const u8 *ec_name, u8 ec_name_len) 227 { 228 const ec_str_params *by_type; 229 const u8 *name; 230 u8 name_len; 231 int ret, check; 232 233 /* No need to bother w/ obvious crap */ 234 MUST_HAVE((ec_name != NULL), ret, err); 235 MUST_HAVE(((ec_name_len > 2) && (ec_name_len <= MAX_CURVE_NAME_LEN)), ret, err); 236 237 /* Let's first do the lookup by type */ 238 ret = ec_get_curve_params_by_type(ec_type, &by_type); EG(ret, err); 239 240 /* Found a curve for that type. Let's check name matches. */ 241 MUST_HAVE((by_type != NULL), ret, err); 242 MUST_HAVE((by_type->name != NULL), ret, err); 243 MUST_HAVE((by_type->name->buf != NULL), ret, err); 244 245 name = by_type->name->buf; 246 name_len = by_type->name->buflen; 247 248 MUST_HAVE((name_len == ec_name_len), ret, err); 249 250 if ((!are_str_equal((const char *)ec_name, (const char *)name, &check)) && (!check)) { 251 ret = -1; 252 } 253 254 err: 255 return ret; 256 } 257