eck_prn.c revision 325335
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@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@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@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 71int 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 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); 78 return (0); 79 } 80 BIO_set_fp(b, fp, BIO_NOCLOSE); 81 ret = ECPKParameters_print(b, x, off); 82 BIO_free(b); 83 return (ret); 84} 85 86int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) 87{ 88 BIO *b; 89 int ret; 90 91 if ((b = BIO_new(BIO_s_file())) == NULL) { 92 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); 93 return (0); 94 } 95 BIO_set_fp(b, fp, BIO_NOCLOSE); 96 ret = EC_KEY_print(b, x, off); 97 BIO_free(b); 98 return (ret); 99} 100 101int ECParameters_print_fp(FILE *fp, const EC_KEY *x) 102{ 103 BIO *b; 104 int ret; 105 106 if ((b = BIO_new(BIO_s_file())) == NULL) { 107 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); 108 return (0); 109 } 110 BIO_set_fp(b, fp, BIO_NOCLOSE); 111 ret = ECParameters_print(b, x); 112 BIO_free(b); 113 return (ret); 114} 115#endif 116 117int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 118{ 119 EVP_PKEY *pk; 120 int ret; 121 pk = EVP_PKEY_new(); 122 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 123 return 0; 124 ret = EVP_PKEY_print_private(bp, pk, off, NULL); 125 EVP_PKEY_free(pk); 126 return ret; 127} 128 129int ECParameters_print(BIO *bp, const EC_KEY *x) 130{ 131 EVP_PKEY *pk; 132 int ret; 133 pk = EVP_PKEY_new(); 134 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 135 return 0; 136 ret = EVP_PKEY_print_params(bp, pk, 4, NULL); 137 EVP_PKEY_free(pk); 138 return ret; 139} 140 141static int print_bin(BIO *fp, const char *str, const unsigned char *num, 142 size_t len, int off); 143 144int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 145{ 146 unsigned char *buffer = NULL; 147 size_t buf_len = 0, i; 148 int ret = 0, reason = ERR_R_BIO_LIB; 149 BN_CTX *ctx = NULL; 150 const EC_POINT *point = NULL; 151 BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, 152 *order = NULL, *cofactor = NULL; 153 const unsigned char *seed; 154 size_t seed_len = 0; 155 156 static const char *gen_compressed = "Generator (compressed):"; 157 static const char *gen_uncompressed = "Generator (uncompressed):"; 158 static const char *gen_hybrid = "Generator (hybrid):"; 159 160 if (!x) { 161 reason = ERR_R_PASSED_NULL_PARAMETER; 162 goto err; 163 } 164 165 ctx = BN_CTX_new(); 166 if (ctx == NULL) { 167 reason = ERR_R_MALLOC_FAILURE; 168 goto err; 169 } 170 171 if (EC_GROUP_get_asn1_flag(x)) { 172 /* the curve parameter are given by an asn1 OID */ 173 int nid; 174 const char *nname; 175 176 if (!BIO_indent(bp, off, 128)) 177 goto err; 178 179 nid = EC_GROUP_get_curve_name(x); 180 if (nid == 0) 181 goto err; 182 183 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) 184 goto err; 185 if (BIO_printf(bp, "\n") <= 0) 186 goto err; 187 nname = EC_curve_nid2nist(nid); 188 if (nname) { 189 if (!BIO_indent(bp, off, 128)) 190 goto err; 191 if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0) 192 goto err; 193 } 194 } else { 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 reason = ERR_R_MALLOC_FAILURE; 207 goto err; 208 } 209#ifndef OPENSSL_NO_EC2M 210 if (is_char_two) { 211 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { 212 reason = ERR_R_EC_LIB; 213 goto err; 214 } 215 } else /* prime field */ 216#endif 217 { 218 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { 219 reason = ERR_R_EC_LIB; 220 goto err; 221 } 222 } 223 224 if ((point = EC_GROUP_get0_generator(x)) == NULL) { 225 reason = ERR_R_EC_LIB; 226 goto err; 227 } 228 if (!EC_GROUP_get_order(x, order, NULL) || 229 !EC_GROUP_get_cofactor(x, cofactor, NULL)) { 230 reason = ERR_R_EC_LIB; 231 goto err; 232 } 233 234 form = EC_GROUP_get_point_conversion_form(x); 235 236 if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { 237 reason = ERR_R_EC_LIB; 238 goto err; 239 } 240 241 buf_len = (size_t)BN_num_bytes(p); 242 if (buf_len < (i = (size_t)BN_num_bytes(a))) 243 buf_len = i; 244 if (buf_len < (i = (size_t)BN_num_bytes(b))) 245 buf_len = i; 246 if (buf_len < (i = (size_t)BN_num_bytes(gen))) 247 buf_len = i; 248 if (buf_len < (i = (size_t)BN_num_bytes(order))) 249 buf_len = i; 250 if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 251 buf_len = i; 252 253 if ((seed = EC_GROUP_get0_seed(x)) != NULL) 254 seed_len = EC_GROUP_get_seed_len(x); 255 256 buf_len += 10; 257 if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 258 reason = ERR_R_MALLOC_FAILURE; 259 goto err; 260 } 261 262 if (!BIO_indent(bp, off, 128)) 263 goto err; 264 265 /* print the 'short name' of the field type */ 266 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) 267 <= 0) 268 goto err; 269 270 if (is_char_two) { 271 /* print the 'short name' of the base type OID */ 272 int basis_type = EC_GROUP_get_basis_type(x); 273 if (basis_type == 0) 274 goto err; 275 276 if (!BIO_indent(bp, off, 128)) 277 goto err; 278 279 if (BIO_printf(bp, "Basis Type: %s\n", 280 OBJ_nid2sn(basis_type)) <= 0) 281 goto err; 282 283 /* print the polynomial */ 284 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, 285 off)) 286 goto err; 287 } else { 288 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) 289 goto err; 290 } 291 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) 292 goto err; 293 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) 294 goto err; 295 if (form == POINT_CONVERSION_COMPRESSED) { 296 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, 297 buffer, off)) 298 goto err; 299 } else if (form == POINT_CONVERSION_UNCOMPRESSED) { 300 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, 301 buffer, off)) 302 goto err; 303 } else { /* form == POINT_CONVERSION_HYBRID */ 304 305 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, 306 buffer, off)) 307 goto err; 308 } 309 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, 310 buffer, off)) 311 goto err; 312 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, 313 buffer, off)) 314 goto err; 315 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) 316 goto err; 317 } 318 ret = 1; 319 err: 320 if (!ret) 321 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); 322 if (p) 323 BN_free(p); 324 if (a) 325 BN_free(a); 326 if (b) 327 BN_free(b); 328 if (gen) 329 BN_free(gen); 330 if (order) 331 BN_free(order); 332 if (cofactor) 333 BN_free(cofactor); 334 if (ctx) 335 BN_CTX_free(ctx); 336 if (buffer != NULL) 337 OPENSSL_free(buffer); 338 return (ret); 339} 340 341static int print_bin(BIO *fp, const char *name, const unsigned char *buf, 342 size_t len, int off) 343{ 344 size_t i; 345 char str[128 + 1 + 4]; 346 347 if (buf == NULL) 348 return 1; 349 if (off > 0) { 350 if (off > 128) 351 off = 128; 352 memset(str, ' ', off); 353 if (BIO_write(fp, str, off) <= 0) 354 return 0; 355 } else { 356 off = 0; 357 } 358 359 if (BIO_printf(fp, "%s", name) <= 0) 360 return 0; 361 362 for (i = 0; i < len; i++) { 363 if ((i % 15) == 0) { 364 str[0] = '\n'; 365 memset(&(str[1]), ' ', off + 4); 366 if (BIO_write(fp, str, off + 1 + 4) <= 0) 367 return 0; 368 } 369 if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 370 0) 371 return 0; 372 } 373 if (BIO_write(fp, "\n", 1) <= 0) 374 return 0; 375 376 return 1; 377} 378