1 /* crypto/ec/eck_prn.c */ 2 /* 3 * Written by Nils Larsch for the OpenSSL project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * openssl-core (at) openssl.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay (at) cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh (at) cryptsoft.com). 56 * 57 */ 58 /* ==================================================================== 59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60 * Portions originally developed by SUN MICROSYSTEMS, INC., and 61 * contributed to the OpenSSL project. 62 */ 63 64 #include <stdio.h> 65 #include "cryptlib.h" 66 #include <openssl/evp.h> 67 #include <openssl/ec.h> 68 #include <openssl/bn.h> 69 70 #ifndef OPENSSL_NO_FP_API 71 int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) 72 { 73 BIO *b; 74 int ret; 75 76 if ((b=BIO_new(BIO_s_file())) == NULL) 77 { 78 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); 79 return(0); 80 } 81 BIO_set_fp(b, fp, BIO_NOCLOSE); 82 ret = ECPKParameters_print(b, x, off); 83 BIO_free(b); 84 return(ret); 85 } 86 87 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) 88 { 89 BIO *b; 90 int ret; 91 92 if ((b=BIO_new(BIO_s_file())) == NULL) 93 { 94 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); 95 return(0); 96 } 97 BIO_set_fp(b, fp, BIO_NOCLOSE); 98 ret = EC_KEY_print(b, x, off); 99 BIO_free(b); 100 return(ret); 101 } 102 103 int ECParameters_print_fp(FILE *fp, const EC_KEY *x) 104 { 105 BIO *b; 106 int ret; 107 108 if ((b=BIO_new(BIO_s_file())) == NULL) 109 { 110 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); 111 return(0); 112 } 113 BIO_set_fp(b, fp, BIO_NOCLOSE); 114 ret = ECParameters_print(b, x); 115 BIO_free(b); 116 return(ret); 117 } 118 #endif 119 120 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 121 { 122 EVP_PKEY *pk; 123 int ret; 124 pk = EVP_PKEY_new(); 125 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 126 return 0; 127 ret = EVP_PKEY_print_private(bp, pk, off, NULL); 128 EVP_PKEY_free(pk); 129 return ret; 130 } 131 132 int ECParameters_print(BIO *bp, const EC_KEY *x) 133 { 134 EVP_PKEY *pk; 135 int ret; 136 pk = EVP_PKEY_new(); 137 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 138 return 0; 139 ret = EVP_PKEY_print_params(bp, pk, 4, NULL); 140 EVP_PKEY_free(pk); 141 return ret; 142 } 143 144 static int print_bin(BIO *fp, const char *str, const unsigned char *num, 145 size_t len, int off); 146 147 int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 148 { 149 unsigned char *buffer=NULL; 150 size_t buf_len=0, i; 151 int ret=0, reason=ERR_R_BIO_LIB; 152 BN_CTX *ctx=NULL; 153 const EC_POINT *point=NULL; 154 BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, 155 *order=NULL, *cofactor=NULL; 156 const unsigned char *seed; 157 size_t seed_len=0; 158 159 static const char *gen_compressed = "Generator (compressed):"; 160 static const char *gen_uncompressed = "Generator (uncompressed):"; 161 static const char *gen_hybrid = "Generator (hybrid):"; 162 163 if (!x) 164 { 165 reason = ERR_R_PASSED_NULL_PARAMETER; 166 goto err; 167 } 168 169 ctx = BN_CTX_new(); 170 if (ctx == NULL) 171 { 172 reason = ERR_R_MALLOC_FAILURE; 173 goto err; 174 } 175 176 if (EC_GROUP_get_asn1_flag(x)) 177 { 178 /* the curve parameter are given by an asn1 OID */ 179 int nid; 180 181 if (!BIO_indent(bp, off, 128)) 182 goto err; 183 184 nid = EC_GROUP_get_curve_name(x); 185 if (nid == 0) 186 goto err; 187 188 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) 189 goto err; 190 if (BIO_printf(bp, "\n") <= 0) 191 goto err; 192 } 193 else 194 { 195 /* explicit parameters */ 196 int is_char_two = 0; 197 point_conversion_form_t form; 198 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); 199 200 if (tmp_nid == NID_X9_62_characteristic_two_field) 201 is_char_two = 1; 202 203 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 204 (b = BN_new()) == NULL || (order = BN_new()) == NULL || 205 (cofactor = BN_new()) == NULL) 206 { 207 reason = ERR_R_MALLOC_FAILURE; 208 goto err; 209 } 210 #ifndef OPENSSL_NO_EC2M 211 if (is_char_two) 212 { 213 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) 214 { 215 reason = ERR_R_EC_LIB; 216 goto err; 217 } 218 } 219 else /* prime field */ 220 #endif 221 { 222 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) 223 { 224 reason = ERR_R_EC_LIB; 225 goto err; 226 } 227 } 228 229 if ((point = EC_GROUP_get0_generator(x)) == NULL) 230 { 231 reason = ERR_R_EC_LIB; 232 goto err; 233 } 234 if (!EC_GROUP_get_order(x, order, NULL) || 235 !EC_GROUP_get_cofactor(x, cofactor, NULL)) 236 { 237 reason = ERR_R_EC_LIB; 238 goto err; 239 } 240 241 form = EC_GROUP_get_point_conversion_form(x); 242 243 if ((gen = EC_POINT_point2bn(x, point, 244 form, NULL, ctx)) == NULL) 245 { 246 reason = ERR_R_EC_LIB; 247 goto err; 248 } 249 250 buf_len = (size_t)BN_num_bytes(p); 251 if (buf_len < (i = (size_t)BN_num_bytes(a))) 252 buf_len = i; 253 if (buf_len < (i = (size_t)BN_num_bytes(b))) 254 buf_len = i; 255 if (buf_len < (i = (size_t)BN_num_bytes(gen))) 256 buf_len = i; 257 if (buf_len < (i = (size_t)BN_num_bytes(order))) 258 buf_len = i; 259 if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 260 buf_len = i; 261 262 if ((seed = EC_GROUP_get0_seed(x)) != NULL) 263 seed_len = EC_GROUP_get_seed_len(x); 264 265 buf_len += 10; 266 if ((buffer = OPENSSL_malloc(buf_len)) == NULL) 267 { 268 reason = ERR_R_MALLOC_FAILURE; 269 goto err; 270 } 271 272 if (!BIO_indent(bp, off, 128)) 273 goto err; 274 275 /* print the 'short name' of the field type */ 276 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) 277 <= 0) 278 goto err; 279 280 if (is_char_two) 281 { 282 /* print the 'short name' of the base type OID */ 283 int basis_type = EC_GROUP_get_basis_type(x); 284 if (basis_type == 0) 285 goto err; 286 287 if (!BIO_indent(bp, off, 128)) 288 goto err; 289 290 if (BIO_printf(bp, "Basis Type: %s\n", 291 OBJ_nid2sn(basis_type)) <= 0) 292 goto err; 293 294 /* print the polynomial */ 295 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, 296 off)) 297 goto err; 298 } 299 else 300 { 301 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off)) 302 goto err; 303 } 304 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) 305 goto err; 306 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) 307 goto err; 308 if (form == POINT_CONVERSION_COMPRESSED) 309 { 310 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, 311 buffer, off)) 312 goto err; 313 } 314 else if (form == POINT_CONVERSION_UNCOMPRESSED) 315 { 316 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, 317 buffer, off)) 318 goto err; 319 } 320 else /* form == POINT_CONVERSION_HYBRID */ 321 { 322 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, 323 buffer, off)) 324 goto err; 325 } 326 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, 327 buffer, off)) goto err; 328 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, 329 buffer, off)) goto err; 330 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) 331 goto err; 332 } 333 ret=1; 334 err: 335 if (!ret) 336 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); 337 if (p) 338 BN_free(p); 339 if (a) 340 BN_free(a); 341 if (b) 342 BN_free(b); 343 if (gen) 344 BN_free(gen); 345 if (order) 346 BN_free(order); 347 if (cofactor) 348 BN_free(cofactor); 349 if (ctx) 350 BN_CTX_free(ctx); 351 if (buffer != NULL) 352 OPENSSL_free(buffer); 353 return(ret); 354 } 355 356 static int print_bin(BIO *fp, const char *name, const unsigned char *buf, 357 size_t len, int off) 358 { 359 size_t i; 360 char str[128]; 361 362 if (buf == NULL) 363 return 1; 364 if (off) 365 { 366 if (off > 128) 367 off=128; 368 memset(str,' ',off); 369 if (BIO_write(fp, str, off) <= 0) 370 return 0; 371 } 372 373 if (BIO_printf(fp,"%s", name) <= 0) 374 return 0; 375 376 for (i=0; i<len; i++) 377 { 378 if ((i%15) == 0) 379 { 380 str[0]='\n'; 381 memset(&(str[1]),' ',off+4); 382 if (BIO_write(fp, str, off+1+4) <= 0) 383 return 0; 384 } 385 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0) 386 return 0; 387 } 388 if (BIO_write(fp,"\n",1) <= 0) 389 return 0; 390 391 return 1; 392 } 393