1238384Sjkim/* crypto/ec/eck_prn.c */ 2238384Sjkim/* 3238384Sjkim * Written by Nils Larsch for the OpenSSL project. 4238384Sjkim */ 5238384Sjkim/* ==================================================================== 6238384Sjkim * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7238384Sjkim * 8238384Sjkim * Redistribution and use in source and binary forms, with or without 9238384Sjkim * modification, are permitted provided that the following conditions 10238384Sjkim * are met: 11238384Sjkim * 12238384Sjkim * 1. Redistributions of source code must retain the above copyright 13238384Sjkim * notice, this list of conditions and the following disclaimer. 14238384Sjkim * 15238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16238384Sjkim * notice, this list of conditions and the following disclaimer in 17238384Sjkim * the documentation and/or other materials provided with the 18238384Sjkim * distribution. 19238384Sjkim * 20238384Sjkim * 3. All advertising materials mentioning features or use of this 21238384Sjkim * software must display the following acknowledgment: 22238384Sjkim * "This product includes software developed by the OpenSSL Project 23238384Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24238384Sjkim * 25238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26238384Sjkim * endorse or promote products derived from this software without 27238384Sjkim * prior written permission. For written permission, please contact 28238384Sjkim * openssl-core@openssl.org. 29238384Sjkim * 30238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 31238384Sjkim * nor may "OpenSSL" appear in their names without prior written 32238384Sjkim * permission of the OpenSSL Project. 33238384Sjkim * 34238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 35238384Sjkim * acknowledgment: 36238384Sjkim * "This product includes software developed by the OpenSSL Project 37238384Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38238384Sjkim * 39238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 51238384Sjkim * ==================================================================== 52238384Sjkim * 53238384Sjkim * This product includes cryptographic software written by Eric Young 54238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 55238384Sjkim * Hudson (tjh@cryptsoft.com). 56238384Sjkim * 57238384Sjkim */ 58238384Sjkim/* ==================================================================== 59238384Sjkim * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60238384Sjkim * Portions originally developed by SUN MICROSYSTEMS, INC., and 61238384Sjkim * contributed to the OpenSSL project. 62238384Sjkim */ 63238384Sjkim 64238384Sjkim#include <stdio.h> 65238384Sjkim#include "cryptlib.h" 66238384Sjkim#include <openssl/evp.h> 67238384Sjkim#include <openssl/ec.h> 68238384Sjkim#include <openssl/bn.h> 69238384Sjkim 70238384Sjkim#ifndef OPENSSL_NO_FP_API 71238384Sjkimint ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) 72238384Sjkim { 73238384Sjkim BIO *b; 74238384Sjkim int ret; 75238384Sjkim 76238384Sjkim if ((b=BIO_new(BIO_s_file())) == NULL) 77238384Sjkim { 78238384Sjkim ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); 79238384Sjkim return(0); 80238384Sjkim } 81238384Sjkim BIO_set_fp(b, fp, BIO_NOCLOSE); 82238384Sjkim ret = ECPKParameters_print(b, x, off); 83238384Sjkim BIO_free(b); 84238384Sjkim return(ret); 85238384Sjkim } 86238384Sjkim 87238384Sjkimint EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) 88238384Sjkim { 89238384Sjkim BIO *b; 90238384Sjkim int ret; 91238384Sjkim 92238384Sjkim if ((b=BIO_new(BIO_s_file())) == NULL) 93238384Sjkim { 94238384Sjkim ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); 95238384Sjkim return(0); 96238384Sjkim } 97238384Sjkim BIO_set_fp(b, fp, BIO_NOCLOSE); 98238384Sjkim ret = EC_KEY_print(b, x, off); 99238384Sjkim BIO_free(b); 100238384Sjkim return(ret); 101238384Sjkim } 102238384Sjkim 103238384Sjkimint ECParameters_print_fp(FILE *fp, const EC_KEY *x) 104238384Sjkim { 105238384Sjkim BIO *b; 106238384Sjkim int ret; 107238384Sjkim 108238384Sjkim if ((b=BIO_new(BIO_s_file())) == NULL) 109238384Sjkim { 110238384Sjkim ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); 111238384Sjkim return(0); 112238384Sjkim } 113238384Sjkim BIO_set_fp(b, fp, BIO_NOCLOSE); 114238384Sjkim ret = ECParameters_print(b, x); 115238384Sjkim BIO_free(b); 116238384Sjkim return(ret); 117238384Sjkim } 118238384Sjkim#endif 119238384Sjkim 120238384Sjkimint EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 121238384Sjkim { 122238384Sjkim EVP_PKEY *pk; 123238384Sjkim int ret; 124238384Sjkim pk = EVP_PKEY_new(); 125238384Sjkim if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 126238384Sjkim return 0; 127238384Sjkim ret = EVP_PKEY_print_private(bp, pk, off, NULL); 128238384Sjkim EVP_PKEY_free(pk); 129238384Sjkim return ret; 130238384Sjkim } 131238384Sjkim 132238384Sjkimint ECParameters_print(BIO *bp, const EC_KEY *x) 133238384Sjkim { 134238384Sjkim EVP_PKEY *pk; 135238384Sjkim int ret; 136238384Sjkim pk = EVP_PKEY_new(); 137238384Sjkim if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) 138238384Sjkim return 0; 139238384Sjkim ret = EVP_PKEY_print_params(bp, pk, 4, NULL); 140238384Sjkim EVP_PKEY_free(pk); 141238384Sjkim return ret; 142238384Sjkim } 143238384Sjkim 144238384Sjkimstatic int print_bin(BIO *fp, const char *str, const unsigned char *num, 145238384Sjkim size_t len, int off); 146238384Sjkim 147238384Sjkimint ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 148238384Sjkim { 149238384Sjkim unsigned char *buffer=NULL; 150238384Sjkim size_t buf_len=0, i; 151238384Sjkim int ret=0, reason=ERR_R_BIO_LIB; 152238384Sjkim BN_CTX *ctx=NULL; 153238384Sjkim const EC_POINT *point=NULL; 154238384Sjkim BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, 155238384Sjkim *order=NULL, *cofactor=NULL; 156238384Sjkim const unsigned char *seed; 157238384Sjkim size_t seed_len=0; 158238384Sjkim 159238384Sjkim static const char *gen_compressed = "Generator (compressed):"; 160238384Sjkim static const char *gen_uncompressed = "Generator (uncompressed):"; 161238384Sjkim static const char *gen_hybrid = "Generator (hybrid):"; 162238384Sjkim 163238384Sjkim if (!x) 164238384Sjkim { 165238384Sjkim reason = ERR_R_PASSED_NULL_PARAMETER; 166238384Sjkim goto err; 167238384Sjkim } 168238384Sjkim 169238384Sjkim ctx = BN_CTX_new(); 170238384Sjkim if (ctx == NULL) 171238384Sjkim { 172238384Sjkim reason = ERR_R_MALLOC_FAILURE; 173238384Sjkim goto err; 174238384Sjkim } 175238384Sjkim 176238384Sjkim if (EC_GROUP_get_asn1_flag(x)) 177238384Sjkim { 178238384Sjkim /* the curve parameter are given by an asn1 OID */ 179238384Sjkim int nid; 180238384Sjkim 181238384Sjkim if (!BIO_indent(bp, off, 128)) 182238384Sjkim goto err; 183238384Sjkim 184238384Sjkim nid = EC_GROUP_get_curve_name(x); 185238384Sjkim if (nid == 0) 186238384Sjkim goto err; 187238384Sjkim 188238384Sjkim if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) 189238384Sjkim goto err; 190238384Sjkim if (BIO_printf(bp, "\n") <= 0) 191238384Sjkim goto err; 192238384Sjkim } 193238384Sjkim else 194238384Sjkim { 195238384Sjkim /* explicit parameters */ 196238384Sjkim int is_char_two = 0; 197238384Sjkim point_conversion_form_t form; 198238384Sjkim int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); 199238384Sjkim 200238384Sjkim if (tmp_nid == NID_X9_62_characteristic_two_field) 201238384Sjkim is_char_two = 1; 202238384Sjkim 203238384Sjkim if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 204238384Sjkim (b = BN_new()) == NULL || (order = BN_new()) == NULL || 205238384Sjkim (cofactor = BN_new()) == NULL) 206238384Sjkim { 207238384Sjkim reason = ERR_R_MALLOC_FAILURE; 208238384Sjkim goto err; 209238384Sjkim } 210238384Sjkim#ifndef OPENSSL_NO_EC2M 211238384Sjkim if (is_char_two) 212238384Sjkim { 213238384Sjkim if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) 214238384Sjkim { 215238384Sjkim reason = ERR_R_EC_LIB; 216238384Sjkim goto err; 217238384Sjkim } 218238384Sjkim } 219238384Sjkim else /* prime field */ 220238384Sjkim#endif 221238384Sjkim { 222238384Sjkim if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) 223238384Sjkim { 224238384Sjkim reason = ERR_R_EC_LIB; 225238384Sjkim goto err; 226238384Sjkim } 227238384Sjkim } 228238384Sjkim 229238384Sjkim if ((point = EC_GROUP_get0_generator(x)) == NULL) 230238384Sjkim { 231238384Sjkim reason = ERR_R_EC_LIB; 232238384Sjkim goto err; 233238384Sjkim } 234238384Sjkim if (!EC_GROUP_get_order(x, order, NULL) || 235238384Sjkim !EC_GROUP_get_cofactor(x, cofactor, NULL)) 236238384Sjkim { 237238384Sjkim reason = ERR_R_EC_LIB; 238238384Sjkim goto err; 239238384Sjkim } 240238384Sjkim 241238384Sjkim form = EC_GROUP_get_point_conversion_form(x); 242238384Sjkim 243238384Sjkim if ((gen = EC_POINT_point2bn(x, point, 244238384Sjkim form, NULL, ctx)) == NULL) 245238384Sjkim { 246238384Sjkim reason = ERR_R_EC_LIB; 247238384Sjkim goto err; 248238384Sjkim } 249238384Sjkim 250238384Sjkim buf_len = (size_t)BN_num_bytes(p); 251238384Sjkim if (buf_len < (i = (size_t)BN_num_bytes(a))) 252238384Sjkim buf_len = i; 253238384Sjkim if (buf_len < (i = (size_t)BN_num_bytes(b))) 254238384Sjkim buf_len = i; 255238384Sjkim if (buf_len < (i = (size_t)BN_num_bytes(gen))) 256238384Sjkim buf_len = i; 257238384Sjkim if (buf_len < (i = (size_t)BN_num_bytes(order))) 258238384Sjkim buf_len = i; 259238384Sjkim if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 260238384Sjkim buf_len = i; 261238384Sjkim 262238384Sjkim if ((seed = EC_GROUP_get0_seed(x)) != NULL) 263238384Sjkim seed_len = EC_GROUP_get_seed_len(x); 264238384Sjkim 265238384Sjkim buf_len += 10; 266238384Sjkim if ((buffer = OPENSSL_malloc(buf_len)) == NULL) 267238384Sjkim { 268238384Sjkim reason = ERR_R_MALLOC_FAILURE; 269238384Sjkim goto err; 270238384Sjkim } 271238384Sjkim 272238384Sjkim if (!BIO_indent(bp, off, 128)) 273238384Sjkim goto err; 274238384Sjkim 275238384Sjkim /* print the 'short name' of the field type */ 276238384Sjkim if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) 277238384Sjkim <= 0) 278238384Sjkim goto err; 279238384Sjkim 280238384Sjkim if (is_char_two) 281238384Sjkim { 282238384Sjkim /* print the 'short name' of the base type OID */ 283238384Sjkim int basis_type = EC_GROUP_get_basis_type(x); 284238384Sjkim if (basis_type == 0) 285238384Sjkim goto err; 286238384Sjkim 287238384Sjkim if (!BIO_indent(bp, off, 128)) 288238384Sjkim goto err; 289238384Sjkim 290238384Sjkim if (BIO_printf(bp, "Basis Type: %s\n", 291238384Sjkim OBJ_nid2sn(basis_type)) <= 0) 292238384Sjkim goto err; 293238384Sjkim 294238384Sjkim /* print the polynomial */ 295238384Sjkim if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, 296238384Sjkim off)) 297238384Sjkim goto err; 298238384Sjkim } 299238384Sjkim else 300238384Sjkim { 301238384Sjkim if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off)) 302238384Sjkim goto err; 303238384Sjkim } 304238384Sjkim if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) 305238384Sjkim goto err; 306238384Sjkim if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) 307238384Sjkim goto err; 308238384Sjkim if (form == POINT_CONVERSION_COMPRESSED) 309238384Sjkim { 310238384Sjkim if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, 311238384Sjkim buffer, off)) 312238384Sjkim goto err; 313238384Sjkim } 314238384Sjkim else if (form == POINT_CONVERSION_UNCOMPRESSED) 315238384Sjkim { 316238384Sjkim if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, 317238384Sjkim buffer, off)) 318238384Sjkim goto err; 319238384Sjkim } 320238384Sjkim else /* form == POINT_CONVERSION_HYBRID */ 321238384Sjkim { 322238384Sjkim if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, 323238384Sjkim buffer, off)) 324238384Sjkim goto err; 325238384Sjkim } 326238384Sjkim if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, 327238384Sjkim buffer, off)) goto err; 328238384Sjkim if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, 329238384Sjkim buffer, off)) goto err; 330238384Sjkim if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) 331238384Sjkim goto err; 332238384Sjkim } 333238384Sjkim ret=1; 334238384Sjkimerr: 335238384Sjkim if (!ret) 336238384Sjkim ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); 337238384Sjkim if (p) 338238384Sjkim BN_free(p); 339238384Sjkim if (a) 340238384Sjkim BN_free(a); 341238384Sjkim if (b) 342238384Sjkim BN_free(b); 343238384Sjkim if (gen) 344238384Sjkim BN_free(gen); 345238384Sjkim if (order) 346238384Sjkim BN_free(order); 347238384Sjkim if (cofactor) 348238384Sjkim BN_free(cofactor); 349238384Sjkim if (ctx) 350238384Sjkim BN_CTX_free(ctx); 351238384Sjkim if (buffer != NULL) 352238384Sjkim OPENSSL_free(buffer); 353238384Sjkim return(ret); 354238384Sjkim } 355238384Sjkim 356238384Sjkimstatic int print_bin(BIO *fp, const char *name, const unsigned char *buf, 357238384Sjkim size_t len, int off) 358238384Sjkim { 359238384Sjkim size_t i; 360238384Sjkim char str[128]; 361238384Sjkim 362238384Sjkim if (buf == NULL) 363238384Sjkim return 1; 364238384Sjkim if (off) 365238384Sjkim { 366238384Sjkim if (off > 128) 367238384Sjkim off=128; 368238384Sjkim memset(str,' ',off); 369238384Sjkim if (BIO_write(fp, str, off) <= 0) 370238384Sjkim return 0; 371238384Sjkim } 372238384Sjkim 373238384Sjkim if (BIO_printf(fp,"%s", name) <= 0) 374238384Sjkim return 0; 375238384Sjkim 376238384Sjkim for (i=0; i<len; i++) 377238384Sjkim { 378238384Sjkim if ((i%15) == 0) 379238384Sjkim { 380238384Sjkim str[0]='\n'; 381238384Sjkim memset(&(str[1]),' ',off+4); 382238384Sjkim if (BIO_write(fp, str, off+1+4) <= 0) 383238384Sjkim return 0; 384238384Sjkim } 385238384Sjkim if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0) 386238384Sjkim return 0; 387238384Sjkim } 388238384Sjkim if (BIO_write(fp,"\n",1) <= 0) 389238384Sjkim return 0; 390238384Sjkim 391238384Sjkim return 1; 392238384Sjkim } 393