int main(int argc, char **argv) { int addrtype = 0; int privtype = 128; int regex = 0; int caseinsensitive = 0; int opt; char pwbuf[128]; int platformidx = -1, deviceidx = -1; int prompt_password = 0; char *seedfile = NULL; char **patterns, *pend; int verbose = 1; int npatterns = 0; int nthreads = 0; int worksize = 0; int nrows = 0, ncols = 0; int invsize = 0; int remove_on_match = 1; int only_one = 0; int verify_mode = 0; int safe_mode = 0; vg_context_t *vcp = NULL; vg_ocl_context_t *vocp = NULL; EC_POINT *pubkey_base = NULL; const char *result_file = NULL; const char *key_password = NULL; char *devstrs[MAX_DEVS]; int ndevstrs = 0; int opened = 0; FILE *pattfp[MAX_FILE], *fp; int pattfpi[MAX_FILE]; int npattfp = 0; int pattstdin = 0; int compressed = 0; int i; while ((opt = getopt(argc, argv, "vqik1NTX:F:eE:p:P:d:w:t:g:b:VSh?f:o:s:D:")) != -1) { switch (opt) { case 'v': verbose = 2; break; case 'q': verbose = 0; break; case 'i': caseinsensitive = 1; break; case 'k': remove_on_match = 0; break; case '1': only_one = 1; break; case 'N': addrtype = 52; privtype = 180; break; case 'T': addrtype = 111; privtype = 239; break; case 'X': addrtype = atoi(optarg); privtype = 128 + addrtype; break; case 'F': if (!strcmp(optarg, "compressed")) compressed = 1; else if (strcmp(optarg, "pubkey")) { fprintf(stderr, "Invalid format '%s'\n", optarg); return 1; } break; case 'e': prompt_password = 1; break; case 'E': key_password = optarg; break; case 'p': platformidx = atoi(optarg); break; case 'd': deviceidx = atoi(optarg); break; case 'w': worksize = atoi(optarg); if (worksize == 0) { fprintf(stderr, "Invalid work size '%s'\n", optarg); return 1; } break; case 't': nthreads = atoi(optarg); if (nthreads == 0) { fprintf(stderr, "Invalid thread count '%s'\n", optarg); return 1; } break; case 'g': nrows = 0; ncols = strtol(optarg, &pend, 0); if (pend && *pend == 'x') { nrows = strtol(pend+1, NULL, 0); } if (!nrows || !ncols) { fprintf(stderr, "Invalid grid size '%s'\n", optarg); return 1; } break; case 'b': invsize = atoi(optarg); if (!invsize) { fprintf(stderr, "Invalid modular inverse size '%s'\n", optarg); return 1; } if (invsize & (invsize - 1)) { fprintf(stderr, "Modular inverse size must be " "a power of 2\n"); return 1; } break; case 'V': verify_mode = 1; break; case 'S': safe_mode = 1; break; case 'D': if (ndevstrs >= MAX_DEVS) { fprintf(stderr, "Too many OpenCL devices (limit %d)\n", MAX_DEVS); return 1; } devstrs[ndevstrs++] = optarg; break; case 'P': { if (pubkey_base != NULL) { fprintf(stderr, "Multiple base pubkeys specified\n"); return 1; } EC_KEY *pkey = vg_exec_context_new_key(); pubkey_base = EC_POINT_hex2point( EC_KEY_get0_group(pkey), optarg, NULL, NULL); EC_KEY_free(pkey); if (pubkey_base == NULL) { fprintf(stderr, "Invalid base pubkey\n"); return 1; } break; } case 'f': if (npattfp >= MAX_FILE) { fprintf(stderr, "Too many input files specified\n"); return 1; } if (!strcmp(optarg, "-")) { if (pattstdin) { fprintf(stderr, "ERROR: stdin " "specified multiple times\n"); return 1; } fp = stdin; } else { fp = fopen(optarg, "r"); if (!fp) { fprintf(stderr, "Could not open %s: %s\n", optarg, strerror(errno)); return 1; } } pattfp[npattfp] = fp; pattfpi[npattfp] = caseinsensitive; npattfp++; break; case 'o': if (result_file) { fprintf(stderr, "Multiple output files specified\n"); return 1; } result_file = optarg; break; case 's': if (seedfile != NULL) { fprintf(stderr, "Multiple RNG seeds specified\n"); return 1; } seedfile = optarg; break; default: usage(argv[0]); return 1; } } #if OPENSSL_VERSION_NUMBER < 0x10000000L /* Complain about older versions of OpenSSL */ if (verbose > 0) { fprintf(stderr, "WARNING: Built with " OPENSSL_VERSION_TEXT "\n" "WARNING: Use OpenSSL 1.0.0d+ for best performance\n"); } #endif if (caseinsensitive && regex) fprintf(stderr, "WARNING: case insensitive mode incompatible with " "regular expressions\n"); if (seedfile) { opt = -1; #if !defined(_WIN32) { struct stat st; if (!stat(seedfile, &st) && (st.st_mode & (S_IFBLK|S_IFCHR))) { opt = 32; } } #endif opt = RAND_load_file(seedfile, opt); if (!opt) { fprintf(stderr, "Could not load RNG seed %s\n", optarg); return 1; } if (verbose > 0) { fprintf(stderr, "Read %d bytes from RNG seed file\n", opt); } } if (regex) { vcp = vg_regex_context_new(addrtype, privtype); } else { vcp = vg_prefix_context_new(addrtype, privtype, caseinsensitive); } vcp->vc_compressed = compressed; vcp->vc_verbose = verbose; vcp->vc_result_file = result_file; vcp->vc_remove_on_match = remove_on_match; vcp->vc_only_one = only_one; vcp->vc_pubkeytype = addrtype; vcp->vc_pubkey_base = pubkey_base; vcp->vc_output_match = vg_output_match_console; vcp->vc_output_timing = vg_output_timing_console; if (!npattfp) { if (optind >= argc) { usage(argv[0]); return 1; } patterns = &argv[optind]; npatterns = argc - optind; if (!vg_context_add_patterns(vcp, (const char ** const) patterns, npatterns)) return 1; } for (i = 0; i < npattfp; i++) { fp = pattfp[i]; if (!vg_read_file(fp, &patterns, &npatterns)) { fprintf(stderr, "Failed to load pattern file\n"); return 1; } if (fp != stdin) fclose(fp); if (!regex) vg_prefix_context_set_case_insensitive(vcp, pattfpi[i]); if (!vg_context_add_patterns(vcp, (const char ** const) patterns, npatterns)) return 1; } if (!vcp->vc_npatterns) { fprintf(stderr, "No patterns to search\n"); return 1; } if (prompt_password) { if (!vg_read_password(pwbuf, sizeof(pwbuf))) return 1; key_password = pwbuf; } vcp->vc_key_protect_pass = key_password; if (key_password) { if (!vg_check_password_complexity(key_password, verbose)) fprintf(stderr, "WARNING: Protecting private keys with " "weak password\n"); } if ((verbose > 0) && regex && (vcp->vc_npatterns > 1)) fprintf(stderr, "Regular expressions: %ld\n", vcp->vc_npatterns); if (ndevstrs) { for (opt = 0; opt < ndevstrs; opt++) { vocp = vg_ocl_context_new_from_devstr(vcp, devstrs[opt], safe_mode, verify_mode); if (!vocp) { fprintf(stderr, "Could not open device '%s', ignoring\n", devstrs[opt]); } else { opened++; } } } else { vocp = vg_ocl_context_new(vcp, platformidx, deviceidx, safe_mode, verify_mode, worksize, nthreads, nrows, ncols, invsize); if (vocp) opened++; } if (!opened) { vg_ocl_enumerate_devices(); return 1; } opt = vg_context_start_threads(vcp); if (opt) return 1; vg_context_wait_for_completion(vcp); vg_ocl_context_free(vocp); return 0; }
/* * Computes gost2001 signature as DSA_SIG structure * * */ DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) { DSA_SIG *newsig = NULL; BIGNUM *md = hashsum2bn(dgst); BIGNUM *order = NULL; const EC_GROUP *group; const BIGNUM *priv_key; BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL; EC_POINT *C=NULL; BN_CTX *ctx = BN_CTX_new(); BN_CTX_start(ctx); OPENSSL_assert(dlen==32); newsig=DSA_SIG_new(); if (!newsig) { GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY); goto err; } group = EC_KEY_get0_group(eckey); order=BN_CTX_get(ctx); EC_GROUP_get_order(group,order,ctx); priv_key = EC_KEY_get0_private_key(eckey); e = BN_CTX_get(ctx); BN_mod(e,md,order,ctx); #ifdef DEBUG_SIGN TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"digest as bignum="); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,md); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\ndigest mod q="); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,e); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\n"); #endif if (BN_is_zero(e)) { BN_one(e); } k =BN_CTX_get(ctx); C=EC_POINT_new(group); do { do { if (!BN_rand_range(k,order)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!X) X=BN_CTX_get(ctx); if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!r) r=BN_CTX_get(ctx); BN_nnmod(r,X,order,ctx); } while (BN_is_zero(r)); /* s = (r*priv_key+k*e) mod order */ if (!tmp) tmp = BN_CTX_get(ctx); BN_mod_mul(tmp,priv_key,r,order,ctx); if (!tmp2) tmp2 = BN_CTX_get(ctx); BN_mod_mul(tmp2,k,e,order,ctx); if (!s) s=BN_CTX_get(ctx); BN_mod_add(s,tmp,tmp2,order,ctx); } while (BN_is_zero(s)); newsig->s=BN_dup(s); newsig->r=BN_dup(r); err: BN_CTX_end(ctx); BN_CTX_free(ctx); EC_POINT_free(C); BN_free(md); return newsig; }
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields // recid selects which key is recovered // if check is non-zero, additional checks are performed int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) { if (!eckey) return 0; const BIGNUM *sig_r, *sig_s; #if OPENSSL_VERSION_NUMBER > 0x1000ffffL ECDSA_SIG_get0(ecsig, &sig_r, &sig_s); #else sig_r = ecsig->r; sig_s = ecsig->s; #endif int ret = 0; BN_CTX *ctx = NULL; BIGNUM *x = NULL; BIGNUM *e = NULL; BIGNUM *order = NULL; BIGNUM *sor = NULL; BIGNUM *eor = NULL; BIGNUM *field = NULL; EC_POINT *R = NULL; EC_POINT *O = NULL; EC_POINT *Q = NULL; BIGNUM *rr = NULL; BIGNUM *zero = NULL; int n = 0; int i = recid / 2; const EC_GROUP *group = EC_KEY_get0_group(eckey); if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } BN_CTX_start(ctx); order = BN_CTX_get(ctx); if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } x = BN_CTX_get(ctx); if (!BN_copy(x, order)) { ret=-1; goto err; } if (!BN_mul_word(x, i)) { ret=-1; goto err; } if (!BN_add(x, x, sig_r)) { ret=-1; goto err; } field = BN_CTX_get(ctx); if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } if (BN_cmp(x, field) >= 0) { ret=0; goto err; } if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } if (check) { if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } } if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } n = EC_GROUP_get_degree(group); e = BN_CTX_get(ctx); if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); zero = BN_CTX_get(ctx); if (!BN_zero(zero)) { ret=-1; goto err; } if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } rr = BN_CTX_get(ctx); if (!BN_mod_inverse(rr, sig_r, order, ctx)) { ret=-1; goto err; } sor = BN_CTX_get(ctx); if (!BN_mod_mul(sor, sig_s, rr, order, ctx)) { ret=-1; goto err; } eor = BN_CTX_get(ctx); if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } ret = 1; err: if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (R != NULL) EC_POINT_free(R); if (O != NULL) EC_POINT_free(O); if (Q != NULL) EC_POINT_free(Q); return ret; }
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, const int engine_impl, EVP_PKEY **ppkey) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; ENGINE *impl = NULL; char *passin = NULL; int rv = -1; X509 *x; if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) || (pkey_op == EVP_PKEY_OP_DERIVE)) && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } switch (key_type) { case KEY_PRIVKEY: pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(keyfile, keyform, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); } break; case KEY_NONE: break; } #ifndef OPENSSL_NO_ENGINE if (engine_impl) impl = e; #endif if (kdfalg != NULL) { int kdfnid = OBJ_sn2nid(kdfalg); if (kdfnid == NID_undef) { kdfnid = OBJ_ln2nid(kdfalg); if (kdfnid == NID_undef) { BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n", kdfalg); goto end; } } ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); } else { EC_KEY *eckey = NULL; const EC_GROUP *group = NULL; int nid; if (pkey == NULL) goto end; /* SM2 needs a special treatment */ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (nid = EC_GROUP_get_curve_name(group)) == 0) goto end; if (nid == NID_sm2) EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); } *pkeysize = EVP_PKEY_size(pkey); ctx = EVP_PKEY_CTX_new(pkey, impl); if (ppkey != NULL) *ppkey = pkey; EVP_PKEY_free(pkey); } if (ctx == NULL) goto end; switch (pkey_op) { case EVP_PKEY_OP_SIGN: rv = EVP_PKEY_sign_init(ctx); break; case EVP_PKEY_OP_VERIFY: rv = EVP_PKEY_verify_init(ctx); break; case EVP_PKEY_OP_VERIFYRECOVER: rv = EVP_PKEY_verify_recover_init(ctx); break; case EVP_PKEY_OP_ENCRYPT: rv = EVP_PKEY_encrypt_init(ctx); break; case EVP_PKEY_OP_DECRYPT: rv = EVP_PKEY_decrypt_init(ctx); break; case EVP_PKEY_OP_DERIVE: rv = EVP_PKEY_derive_init(ctx); break; } if (rv <= 0) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } end: OPENSSL_free(passin); return ctx; }
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) { EC_KEY *a=NULL; EC_KEY *b=NULL; BIGNUM *x_a=NULL, *y_a=NULL, *x_b=NULL, *y_b=NULL; char buf[12]; unsigned char *abuf=NULL,*bbuf=NULL; int i,alen,blen,aout,bout,ret=0; const EC_GROUP *group; a = EC_KEY_new_by_curve_name(nid); b = EC_KEY_new_by_curve_name(nid); if (a == NULL || b == NULL) goto err; group = EC_KEY_get0_group(a); if ((x_a=BN_new()) == NULL) goto err; if ((y_a=BN_new()) == NULL) goto err; if ((x_b=BN_new()) == NULL) goto err; if ((y_b=BN_new()) == NULL) goto err; BIO_puts(out,"Testing key generation with "); BIO_puts(out,text); #ifdef NOISY BIO_puts(out,"\n"); #else (void)BIO_flush(out); #endif if (!EC_KEY_generate_key(a)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } #ifdef NOISY BIO_puts(out," pri 1="); BN_print(out,a->priv_key); BIO_puts(out,"\n pub 1="); BN_print(out,x_a); BIO_puts(out,","); BN_print(out,y_a); BIO_puts(out,"\n"); #else BIO_printf(out," ."); (void)BIO_flush(out); #endif if (!EC_KEY_generate_key(b)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } #ifdef NOISY BIO_puts(out," pri 2="); BN_print(out,b->priv_key); BIO_puts(out,"\n pub 2="); BN_print(out,x_b); BIO_puts(out,","); BN_print(out,y_b); BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif alen=KDF1_SHA1_len; abuf=(unsigned char *)OPENSSL_malloc(alen); aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1); #ifdef NOISY BIO_puts(out," key1 ="); for (i=0; i<aout; i++) { TINYCLR_SSL_SPRINTF(buf,"%02X",abuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif blen=KDF1_SHA1_len; bbuf=(unsigned char *)OPENSSL_malloc(blen); bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1); #ifdef NOISY BIO_puts(out," key2 ="); for (i=0; i<bout; i++) { TINYCLR_SSL_SPRINTF(buf,"%02X",bbuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif if ((aout < 4) || (bout != aout) || (TINYCLR_SSL_MEMCMP(abuf,bbuf,aout) != 0)) { #ifndef NOISY BIO_printf(out, " failed\n\n"); BIO_printf(out, "key a:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(a)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_a); BIO_printf(out, ","); BN_print(out, y_a); BIO_printf(out, "\nkey b:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(b)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_b); BIO_printf(out, ","); BN_print(out, y_b); BIO_printf(out, "\n"); BIO_printf(out, "generated key a: "); for (i=0; i<bout; i++) { TINYCLR_SSL_SPRINTF(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_printf(out, "\n"); BIO_printf(out, "generated key b: "); for (i=0; i<aout; i++) { TINYCLR_SSL_SPRINTF(buf, "%02X", abuf[i]); BIO_puts(out,buf); } BIO_printf(out, "\n"); #endif TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"Error in ECDH routines\n"); ret=0; } else { #ifndef NOISY BIO_printf(out, " ok\n"); #endif ret=1; } err: ERR_print_errors_fp(OPENSSL_TYPE__FILE_STDERR); if (abuf != NULL) OPENSSL_free(abuf); if (bbuf != NULL) OPENSSL_free(bbuf); if (x_a) BN_free(x_a); if (y_a) BN_free(y_a); if (x_b) BN_free(x_b); if (y_b) BN_free(y_b); if (b) EC_KEY_free(b); if (a) EC_KEY_free(a); return(ret); }
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { unsigned char *buffer=NULL; const char *ecstr; size_t buf_len=0, i; int ret=0, reason=ERR_R_BIO_LIB; BIGNUM *pub_key=NULL, *order=NULL; BN_CTX *ctx=NULL; const EC_GROUP *group; const EC_POINT *public_key; const BIGNUM *priv_key; if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } ctx = BN_CTX_new(); if (ctx == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } if (ktype > 0) { public_key = EC_KEY_get0_public_key(x); if ((pub_key = EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { reason = ERR_R_EC_LIB; goto err; } if (pub_key) buf_len = (size_t)BN_num_bytes(pub_key); } if (ktype == 2) { priv_key = EC_KEY_get0_private_key(x); if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) buf_len = i; } else priv_key = NULL; if (ktype > 0) { buf_len += 10; if ((buffer = (unsigned char*)OPENSSL_malloc(buf_len)) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } } if (ktype == 2) ecstr = "Private-Key"; else if (ktype == 1) ecstr = "Public-Key"; else ecstr = "ECDSA-Parameters"; if (!BIO_indent(bp, off, 128)) goto err; if ((order = BN_new()) == NULL) goto err; if (!EC_GROUP_get_order(group, order, NULL)) goto err; if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) goto err; if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) goto err; if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, buffer, off)) goto err; if (!ECPKParameters_print(bp, group, off)) goto err; ret=1; err: if (!ret) ECerr(EC_F_DO_EC_KEY_PRINT, reason); if (pub_key) BN_free(pub_key); if (order) BN_free(order); if (ctx) BN_CTX_free(ctx); if (buffer != NULL) OPENSSL_free(buffer); return(ret); }
int main(int argc, char **argv) { int addrtype = 0; int scriptaddrtype = 5; int privtype = 128; int pubkeytype; enum vg_format format = VCF_PUBKEY; int regex = 0; int caseinsensitive = 0; int verbose = 1; int simulate = 0; int remove_on_match = 1; int only_one = 0; int prompt_password = 0; int opt; char *seedfile = NULL; char pwbuf[128]; const char *result_file = NULL; const char *key_password = NULL; char **patterns; int npatterns = 0; int nthreads = 0; vg_context_t *vcp = NULL; EC_POINT *pubkey_base = NULL; FILE *pattfp[MAX_FILE], *fp; int pattfpi[MAX_FILE]; int npattfp = 0; int pattstdin = 0; int compressed = 1; int i; while ((opt = getopt(argc, argv, "vqnrik1eE:P:NTX:F:t:h?f:o:s:")) != -1) { switch (opt) { case 'v': verbose = 2; break; case 'q': verbose = 0; break; case 'n': simulate = 1; break; case 'r': regex = 1; break; case 'i': caseinsensitive = 1; break; case 'k': remove_on_match = 0; break; case '1': only_one = 1; break; case 'N': addrtype = 52; privtype = 180; scriptaddrtype = -1; break; case 'T': addrtype = 111; privtype = 239; scriptaddrtype = 196; break; case 'X': addrtype = atoi(optarg); privtype = 128 + addrtype; scriptaddrtype = addrtype; break; case 'F': if (!strcmp(optarg, "script")){ format = VCF_SCRIPT; } else if(!strcmp(optarg,"uncompressed")){ compressed = 0; }else if (strcmp(optarg, "pubkey")) { fprintf(stderr, "Invalid format '%s'\n", optarg); return 1; } break; case 'P': { if (pubkey_base != NULL) { fprintf(stderr, "Multiple base pubkeys specified\n"); return 1; } EC_KEY *pkey = vg_exec_context_new_key(); pubkey_base = EC_POINT_hex2point( EC_KEY_get0_group(pkey), optarg, NULL, NULL); EC_KEY_free(pkey); if (pubkey_base == NULL) { fprintf(stderr, "Invalid base pubkey\n"); return 1; } break; } case 'e': prompt_password = 1; break; case 'E': key_password = optarg; break; case 't': nthreads = atoi(optarg); if (nthreads == 0) { fprintf(stderr, "Invalid thread count '%s'\n", optarg); return 1; } break; case 'f': if (npattfp >= MAX_FILE) { fprintf(stderr, "Too many input files specified\n"); return 1; } if (!strcmp(optarg, "-")) { if (pattstdin) { fprintf(stderr, "ERROR: stdin " "specified multiple times\n"); return 1; } fp = stdin; } else { fp = fopen(optarg, "r"); if (!fp) { fprintf(stderr, "Could not open %s: %s\n", optarg, strerror(errno)); return 1; } } pattfp[npattfp] = fp; pattfpi[npattfp] = caseinsensitive; npattfp++; break; case 'o': if (result_file) { fprintf(stderr, "Multiple output files specified\n"); return 1; } result_file = optarg; break; case 's': if (seedfile != NULL) { fprintf(stderr, "Multiple RNG seeds specified\n"); return 1; } seedfile = optarg; break; default: usage(argv[0]); return 1; } } #if OPENSSL_VERSION_NUMBER < 0x10000000L /* Complain about older versions of OpenSSL */ if (verbose > 0) { fprintf(stderr, "WARNING: Built with " OPENSSL_VERSION_TEXT "\n" "WARNING: Use OpenSSL 1.0.0d+ for best performance\n"); } #endif if (caseinsensitive && regex) fprintf(stderr, "WARNING: case insensitive mode incompatible with " "regular expressions\n"); pubkeytype = addrtype; if (format == VCF_SCRIPT) { if (scriptaddrtype == -1) { fprintf(stderr, "Address type incompatible with script format\n"); return 1; } addrtype = scriptaddrtype; } if (seedfile) { opt = -1; #if !defined(_WIN32) { struct stat st; if (!stat(seedfile, &st) && (st.st_mode & (S_IFBLK|S_IFCHR))) { opt = 32; } } #endif opt = RAND_load_file(seedfile, opt); if (!opt) { fprintf(stderr, "Could not load RNG seed %s\n", optarg); return 1; } if (verbose > 0) { fprintf(stderr, "Read %d bytes from RNG seed file\n", opt); } } if (regex) { vcp = vg_regex_context_new(addrtype, privtype); } else { vcp = vg_prefix_context_new(addrtype, privtype, caseinsensitive); } vcp->vc_compressed=compressed; vcp->vc_verbose = verbose; vcp->vc_result_file = result_file; vcp->vc_remove_on_match = remove_on_match; vcp->vc_only_one = only_one; vcp->vc_format = format; vcp->vc_pubkeytype = pubkeytype; vcp->vc_pubkey_base = pubkey_base; vcp->vc_output_match = vg_output_match_console; vcp->vc_output_timing = vg_output_timing_console; if (!npattfp) { if (optind >= argc) { usage(argv[0]); return 1; } patterns = &argv[optind]; npatterns = argc - optind; if (!vg_context_add_patterns(vcp, (const char ** const) patterns, npatterns)) return 1; } for (i = 0; i < npattfp; i++) { fp = pattfp[i]; if (!vg_read_file(fp, &patterns, &npatterns)) { fprintf(stderr, "Failed to load pattern file\n"); return 1; } if (fp != stdin) fclose(fp); if (!regex) vg_prefix_context_set_case_insensitive(vcp, pattfpi[i]); if (!vg_context_add_patterns(vcp, (const char ** const) patterns, npatterns)) return 1; } if (!vcp->vc_npatterns) { fprintf(stderr, "No patterns to search\n"); return 1; } if (prompt_password) { if (!vg_read_password(pwbuf, sizeof(pwbuf))) return 1; key_password = pwbuf; } vcp->vc_key_protect_pass = key_password; if (key_password) { if (!vg_check_password_complexity(key_password, verbose)) fprintf(stderr, "WARNING: Protecting private keys with " "weak password\n"); } if ((verbose > 0) && regex && (vcp->vc_npatterns > 1)) fprintf(stderr, "Regular expressions: %ld\n", vcp->vc_npatterns); if (simulate) return 0; if (!start_threads(vcp, nthreads)) return 1; return 0; }
int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; BIGNUM *sig_r, *sig_s; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (RAND_bytes(digest, 20) <= 0 || RAND_bytes(wrong_digest, 20) <= 0) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* * create and verify a ecdsa signature with every availble curve (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(*curves) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4 || nid == NID_X25519) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) { /* drop the curve */ EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong length */ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* * Modify a single byte of the signature: to ensure we don't garble * the ASN1 structure, we read the raw signature and modify a byte in * one of the bignums directly. */ sig_ptr = signature; if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { BIO_printf(out, " failed\n"); goto builtin_err; } ECDSA_SIG_get0(&sig_r, &sig_s, ecdsa_sig); /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(sig_r); s_len = BN_num_bytes(sig_s); bn_len = (degree + 7) / 8; if ((r_len > bn_len) || (s_len > bn_len)) { BIO_printf(out, " failed\n"); goto builtin_err; } buf_len = 2 * bn_len; if ((raw_buf = OPENSSL_zalloc(buf_len)) == NULL) goto builtin_err; BN_bn2bin(sig_r, raw_buf + bn_len - r_len); BN_bn2bin(sig_s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if ((BN_bin2bn(raw_buf, bn_len, sig_r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, sig_s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } /* * Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if ((BN_bin2bn(raw_buf, bn_len, sig_r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, sig_s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ /* clean bogus errors */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: EC_KEY_free(eckey); EC_KEY_free(wrong_eckey); ECDSA_SIG_free(ecdsa_sig); OPENSSL_free(signature); OPENSSL_free(raw_buf); OPENSSL_free(curves); return ret; }
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0, i; BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; const BIGNUM *ckinv; BN_CTX *ctx = NULL; const EC_GROUP *group; ECDSA_SIG *ret; ECDSA_DATA *ecdsa; const BIGNUM *priv_key; ecdsa = ecdsa_check(eckey); group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); if (group == NULL || priv_key == NULL || ecdsa == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); return NULL; } ret = ECDSA_SIG_new(); if (!ret) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); return NULL; } s = ret->s; if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); goto err; } i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } do { if (in_kinv == NULL || in_r == NULL) { if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB); goto err; } ckinv = kinv; } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } } if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (!BN_mod_add_quick(s, tmp, m, order)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (!BN_mod_mul(s, s, ckinv, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (BN_is_zero(s)) { /* * if kinv and r have been supplied by the caller don't to * generate new kinv and r values */ if (in_kinv != NULL && in_r != NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); goto err; } } else /* s != 0 => we have a valid signature */ break; } while (1); ok = 1; err: if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } if (ctx) BN_CTX_free(ctx); if (m) BN_clear_free(m); if (tmp) BN_clear_free(tmp); if (order) BN_free(order); if (kinv) BN_clear_free(kinv); return ret; }
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){ /* ECDH keys */ ssh_string q_c_string; ssh_string q_s_string; EC_KEY *ecdh_key; const EC_GROUP *group; const EC_POINT *ecdh_pubkey; bignum_CTX ctx; /* SSH host keys (rsa,dsa,ecdsa) */ ssh_key privkey; ssh_string sig_blob = NULL; int len; int rc; /* Extract the client pubkey from the init packet */ q_c_string = buffer_get_ssh_string(packet); if (q_c_string == NULL) { ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet"); return SSH_ERROR; } session->next_crypto->ecdh_client_pubkey = q_c_string; /* Build server's keypair */ ctx = BN_CTX_new(); ecdh_key = EC_KEY_new_by_curve_name(NISTP256); if (ecdh_key == NULL) { ssh_set_error_oom(session); BN_CTX_free(ctx); return SSH_ERROR; } group = EC_KEY_get0_group(ecdh_key); EC_KEY_generate_key(ecdh_key); ecdh_pubkey = EC_KEY_get0_public_key(ecdh_key); len = EC_POINT_point2oct(group, ecdh_pubkey, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, ctx); q_s_string = ssh_string_new(len); if (q_s_string == NULL) { EC_KEY_free(ecdh_key); BN_CTX_free(ctx); return SSH_ERROR; } EC_POINT_point2oct(group, ecdh_pubkey, POINT_CONVERSION_UNCOMPRESSED, ssh_string_data(q_s_string), len, ctx); BN_CTX_free(ctx); session->next_crypto->ecdh_privkey = ecdh_key; session->next_crypto->ecdh_server_pubkey = q_s_string; rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY); if (rc < 0) { ssh_set_error_oom(session); return SSH_ERROR; } /* build k and session_id */ rc = ecdh_build_k(session); if (rc < 0) { ssh_set_error(session, SSH_FATAL, "Cannot build k number"); return SSH_ERROR; } /* privkey is not allocated */ rc = ssh_get_key_params(session, &privkey); if (rc == SSH_ERROR) { return SSH_ERROR; } rc = make_sessionid(session); if (rc != SSH_OK) { ssh_set_error(session, SSH_FATAL, "Could not create a session id"); return SSH_ERROR; } /* add host's public key */ rc = buffer_add_ssh_string(session->out_buffer, session->next_crypto->server_pubkey); if (rc < 0) { ssh_set_error_oom(session); return SSH_ERROR; } /* add ecdh public key */ rc = buffer_add_ssh_string(session->out_buffer, q_s_string); if (rc < 0) { ssh_set_error_oom(session); return SSH_ERROR; } /* add signature blob */ sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); return SSH_ERROR; } rc = buffer_add_ssh_string(session->out_buffer, sig_blob); ssh_string_free(sig_blob); if (rc < 0) { ssh_set_error_oom(session); return SSH_ERROR; } SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent"); rc = packet_send(session); if (rc == SSH_ERROR) { return SSH_ERROR; } /* Send the MSG_NEWKEYS */ rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); if (rc < 0) { return SSH_ERROR;; } session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; rc = packet_send(session); SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); return rc; }
/*- * This implementation is based on the following primitives in the IEEE 1363 standard: * - ECKAS-DH1 * - ECSVDP-DH */ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh) { BN_CTX *ctx; EC_POINT *tmp = NULL; BIGNUM *x = NULL, *y = NULL; const BIGNUM *priv_key; const EC_GROUP *group; int ret = 0; size_t buflen, len; unsigned char *buf = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); priv_key = EC_KEY_get0_private_key(ecdh); if (priv_key == NULL) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE); goto err; } group = EC_KEY_get0_group(ecdh); if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { if (!EC_GROUP_get_cofactor(group, x, NULL) || !BN_mul(x, x, priv_key, ctx)) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; } priv_key = x; } if ((tmp = EC_POINT_new(group)) == NULL) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE); goto err; } } #ifndef OPENSSL_NO_EC2M else { if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE); goto err; } } #endif buflen = (EC_GROUP_get_degree(group) + 7) / 8; len = BN_num_bytes(x); if (len > buflen) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } if ((buf = OPENSSL_malloc(buflen)) == NULL) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; } memset(buf, 0, buflen - len); if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB); goto err; } *pout = buf; *poutlen = buflen; buf = NULL; ret = 1; err: EC_POINT_free(tmp); if (ctx) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_free(buf); return ret; }
int main(int argc, char *argv[]) { void *bb; BN_CTX *ctx = NULL; int nid; BIO *out; CRYPTO_malloc_debug_init(); CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); const char *text = "NIST Prime-Curve P-192"; #ifdef OPENSSL_SYS_WIN32 CRYPTO_malloc_init(); #endif RAND_seed(rnd_seed, sizeof rnd_seed); out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE); if ((ctx = BN_CTX_new()) == NULL) goto err; nid = NID_X9_62_prime192v1; //EC_POINT *bb; EC_KEY *a = NULL; //EC_KEY is a structure BIGNUM *x_a = NULL, *y_a = NULL; char buf[12]; //unsigned char *abuf=NULL,*bbuf=NULL; int i, alen, blen, aout, bout; const EC_GROUP *group; a = EC_KEY_new_by_curve_name(nid); if (a == NULL) goto err; group = EC_KEY_get0_group(a); if ((x_a = BN_new()) == NULL) goto err; //BN_new returns a pointer to the bignum if ((y_a = BN_new()) == NULL) goto err; BIO_puts(out, "Testing key generation with "); BIO_puts(out, text); if (!EC_KEY_generate_key(a)) goto err; printf("\n1 ) generating keys\n"); if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } //returns the public key else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } BIO_puts(out, " pri 1="); BN_print(out, EC_KEY_get0_private_key(a)); BIO_puts(out, "\n pub 1="); BN_print(out, x_a); BIO_puts(out, ","); BN_print(out, y_a); BIO_puts(out, "\n"); func(EC_KEY_get0_public_key(a)); err: ERR_print_errors_fp(stderr); if (x_a) BN_free(x_a); if (y_a) BN_free(y_a); if (a) EC_KEY_free(a); if (ctx) BN_CTX_free(ctx); BIO_free(out); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); CRYPTO_mem_leaks_fp(stderr); return 0; }
void sshkey_file_tests(void) { struct sshkey *k1, *k2; struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; char *cp; const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key; TEST_START("load passphrase"); pw = load_text_file("pw"); TEST_DONE(); TEST_START("parse RSA from private"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa_1.param.n"); b = load_bignum("rsa_1.param.p"); c = load_bignum("rsa_1.param.q"); RSA_get0_key(k1->rsa, &n, NULL, NULL); RSA_get0_factors(k1->rsa, &p, &q); ASSERT_BIGNUM_EQ(n, a); ASSERT_BIGNUM_EQ(p, b); ASSERT_BIGNUM_EQ(q, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse RSA from private w/ passphrase"); buf = load_file("rsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format"); buf = load_file("rsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format w/ passphrase"); buf = load_file("rsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_RSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("RSA key hex fingerprint"); buf = load_text_file("rsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("RSA cert hex fingerprint"); buf = load_text_file("rsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("RSA key bubblebabble fingerprint"); buf = load_text_file("rsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); TEST_START("parse DSA from private"); buf = load_file("dsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("dsa_1.param.g"); b = load_bignum("dsa_1.param.priv"); c = load_bignum("dsa_1.param.pub"); DSA_get0_pqg(k1->dsa, NULL, NULL, &g); DSA_get0_key(k1->dsa, &pub_key, &priv_key); ASSERT_BIGNUM_EQ(g, a); ASSERT_BIGNUM_EQ(priv_key, b); ASSERT_BIGNUM_EQ(pub_key, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse DSA from private w/ passphrase"); buf = load_file("dsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format"); buf = load_file("dsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format w/ passphrase"); buf = load_file("dsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("DSA key hex fingerprint"); buf = load_text_file("dsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("DSA cert hex fingerprint"); buf = load_text_file("dsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("DSA key bubblebabble fingerprint"); buf = load_text_file("dsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); buf = load_text_file("ecdsa_1.param.curve"); ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf), OBJ_nid2sn(k1->ecdsa_nid)); sshbuf_free(buf); a = load_bignum("ecdsa_1.param.priv"); b = load_bignum("ecdsa_1.param.pub"); c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); ASSERT_PTR_NE(c, NULL); ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); ASSERT_BIGNUM_EQ(b, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse ECDSA from private w/ passphrase"); buf = load_file("ecdsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format"); buf = load_file("ecdsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format w/ passphrase"); buf = load_file("ecdsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("ECDSA key hex fingerprint"); buf = load_text_file("ecdsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("ECDSA cert hex fingerprint"); buf = load_text_file("ecdsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("ECDSA key bubblebabble fingerprint"); buf = load_text_file("ecdsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #endif /* OPENSSL_HAS_ECC */ TEST_START("parse Ed25519 from private"); buf = load_file("ed25519_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); ASSERT_INT_EQ(k1->type, KEY_ED25519); /* XXX check key contents */ TEST_DONE(); TEST_START("parse Ed25519 from private w/ passphrase"); buf = load_file("ed25519_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("Ed25519 key hex fingerprint"); buf = load_text_file("ed25519_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("Ed25519 cert hex fingerprint"); buf = load_text_file("ed25519_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("Ed25519 key bubblebabble fingerprint"); buf = load_text_file("ed25519_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); sshbuf_free(pw); }
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; EC_POINT *tmp_point=NULL; const EC_GROUP *group; int ret = 0; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); return 0; } } else ctx = ctx_in; k = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ order = BN_new(); X = BN_new(); if (!k || !r || !order || !X) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } do { /* get random k */ do if (!BN_rand_range(k, order)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } while (BN_is_zero(k)); /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } else /* NID_X9_62_characteristic_two_field */ { if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } if (!BN_nnmod(r, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* compute the inverse of k */ if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } /* clear old values if necessary */ if (*rp != NULL) BN_clear_free(*rp); if (*kinvp != NULL) BN_clear_free(*kinvp); /* save the pre-computed values */ *rp = r; *kinvp = k; ret = 1; err: if (!ret) { if (k != NULL) BN_clear_free(k); if (r != NULL) BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); if (order != NULL) BN_free(order); if (tmp_point != NULL) EC_POINT_free(tmp_point); if (X) BN_clear_free(X); return(ret); }
static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); eckey = eckey_type2param(ptype, pval); if (!eckey) goto ecliberr; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; ecliberr: ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); ecerr: if (eckey) EC_KEY_free(eckey); return 0; }
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, i; BN_CTX *ctx; BIGNUM *order, *u1, *u2, *m, *X; EC_POINT *point = NULL; const EC_GROUP *group; const EC_POINT *pub_key; /* check input values */ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); return -1; } ctx = BN_CTX_new(); if (!ctx) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); return -1; } BN_CTX_start(ctx); order = BN_CTX_get(ctx); u1 = BN_CTX_get(ctx); u2 = BN_CTX_get(ctx); m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); if (!X) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); ret = 0; /* signature is invalid */ goto err; } /* calculate tmp1 = inv(S) mod order */ if (!BN_mod_inverse(u2, sig->s, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* digest -> m */ i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* u1 = m * tmp mod order */ if (!BN_mod_mul(u1, m, u2, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* u2 = r * w mod q */ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if ((point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else { /* NID_X9_62_characteristic_two_field */ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } #endif if (!BN_nnmod(u1, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* if the signature is correct u1 is equal to sig->r */ ret = (BN_ucmp(u1, sig->r) == 0); err: BN_CTX_end(ctx); BN_CTX_free(ctx); if (point) EC_POINT_free(point); return ret; }
static int ec_missing_parameters(const EVP_PKEY *pkey) { if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) return 1; return 0; }
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); return 0; } } else ctx = ctx_in; k = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ order = BN_new(); X = BN_new(); if (!k || !r || !order || !X) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } do { /* get random k */ do if (!BN_rand_range(k, order)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } while (BN_is_zero(k)) ; /* * We do not want timing information to leak the length of k, so we * compute G*k using an equivalent scalar of fixed bit-length. */ if (!BN_add(k, k, order)) goto err; if (BN_num_bits(k) <= BN_num_bits(order)) if (!BN_add(k, k, order)) goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp (group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else { /* NID_X9_62_characteristic_two_field */ if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } } #endif if (!BN_nnmod(r, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* compute the inverse of k */ if (EC_GROUP_get_mont_data(group) != NULL) { /* * We want inverse in constant time, therefore we utilize the fact * order must be prime and use Fermats Little Theorem instead. */ if (!BN_set_word(X, 2)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } if (!BN_mod_sub(X, order, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } BN_set_flags(X, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } else { if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } /* clear old values if necessary */ if (*rp != NULL) BN_clear_free(*rp); if (*kinvp != NULL) BN_clear_free(*kinvp); /* save the pre-computed values */ *rp = r; *kinvp = k; ret = 1; err: if (!ret) { if (k != NULL) BN_clear_free(k); if (r != NULL) BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); if (order != NULL) BN_free(order); if (tmp_point != NULL) EC_POINT_free(tmp_point); if (X) BN_clear_free(X); return (ret); }
/* Our version of the ossl_ecdh_compute_key replaced in the EC_KEY_METHOD */ static int pkcs11_ec_ckey(void *out, size_t outlen, const EC_POINT *ecpointpeer, const EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)) { int ret = -1; size_t buflen; unsigned char *buf = NULL; size_t peerbuflen; unsigned char *peerbuf = NULL; const EC_GROUP *ecgroup = NULL; const EC_POINT *ecpoint = NULL; CK_ECDH1_DERIVE_PARAMS ecdh_parms; PKCS11_KEY * key = NULL; key = (PKCS11_KEY *) EC_KEY_get_ex_data(ecdh, ec_key_ex_index); if (key == NULL) { ret -1; goto err; } /* both peer and ecdh use same group parameters */ ecgroup = EC_KEY_get0_group(ecdh); buflen = (EC_GROUP_get_degree(ecgroup) + 7) / 8; peerbuflen = 2*buflen + 1; peerbuf = OPENSSL_malloc(peerbuflen); if (peerbuf == NULL) { ret = -1; goto err; } ecdh_parms.kdf = CKD_NULL; ecdh_parms.ulSharedDataLen = 0; ecdh_parms.pSharedData = NULL; ecdh_parms.ulPublicDataLen = peerbuflen; ret = EC_POINT_point2oct(ecgroup, ecpointpeer, POINT_CONVERSION_UNCOMPRESSED, peerbuf, peerbuflen,NULL); ecdh_parms.ulPublicDataLen = peerbuflen; ecdh_parms.pPublicData = peerbuf; ret = pkcs11_ecdh_derive_internal(&buf, &buflen, CKM_ECDH1_DERIVE, (const void *)&ecdh_parms, NULL, key); if (KDF != 0) { if (KDF(buf, buflen, out, &outlen) == NULL) { ret -1; goto err; } ret = outlen; } else { if (outlen > buflen) outlen = buflen; memcpy(out, buf, outlen); ret = outlen; } err: OPENSSL_free(buf); return (ret); }
void vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey, const char *pattern) { unsigned char key_buf[512], *pend; char addr_buf[64], addr2_buf[64]; char privkey_buf[VG_PROTKEY_MAX_B58]; const char *keytype = "Privkey"; int len; int isscript = (vcp->vc_format == VCF_SCRIPT); EC_POINT *ppnt; int free_ppnt = 0; if (vcp->vc_pubkey_base) { ppnt = EC_POINT_new(EC_KEY_get0_group(pkey)); EC_POINT_copy(ppnt, EC_KEY_get0_public_key(pkey)); EC_POINT_add(EC_KEY_get0_group(pkey), ppnt, ppnt, vcp->vc_pubkey_base, NULL); free_ppnt = 1; keytype = "PrivkeyPart"; } else { ppnt = (EC_POINT *) EC_KEY_get0_public_key(pkey); } assert(EC_KEY_check_key(pkey)); vg_encode_address(ppnt, EC_KEY_get0_group(pkey), vcp->vc_pubkeytype, addr_buf); if (isscript) vg_encode_script_address(ppnt, EC_KEY_get0_group(pkey), vcp->vc_addrtype, addr2_buf); if (vcp->vc_key_protect_pass) { len = vg_protect_encode_privkey(privkey_buf, pkey, vcp->vc_privtype, VG_PROTKEY_DEFAULT, vcp->vc_key_protect_pass); if (len) { keytype = "Protkey"; } else { fprintf(stderr, "ERROR: could not password-protect key\n"); vcp->vc_key_protect_pass = NULL; } } if (!vcp->vc_key_protect_pass) { vg_encode_privkey(pkey, vcp->vc_privtype, privkey_buf); } if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) { printf("\r%79s\rPattern: %s\n", "", pattern); } if (vcp->vc_verbose > 0) { if (vcp->vc_verbose > 1) { pend = key_buf; len = i2o_ECPublicKey(pkey, &pend); printf("Pubkey (hex): "); dumphex(key_buf, len); printf("Privkey (hex): "); dumpbn(EC_KEY_get0_private_key(pkey)); pend = key_buf; len = i2d_ECPrivateKey(pkey, &pend); printf("Privkey (ASN1): "); dumphex(key_buf, len); } } if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) { if (isscript) printf("P2SHAddress: %s\n", addr2_buf); printf("Address: %s\n" "%s: %s\n", addr_buf, keytype, privkey_buf); } if (vcp->vc_result_file) { FILE *fp = fopen(vcp->vc_result_file, "a"); if (!fp) { fprintf(stderr, "ERROR: could not open result file: %s\n", strerror(errno)); } else { fprintf(fp, "Pattern: %s\n" , pattern); if (isscript) fprintf(fp, "P2SHAddress: %s\n", addr2_buf); fprintf(fp, "Address: %s\n" "%s: %s\n", addr_buf, keytype, privkey_buf); fclose(fp); } } if (free_ppnt) EC_POINT_free(ppnt); }
void * vg_thread_loop(void *arg) { unsigned char hash_buf[128]; unsigned char *eckey_buf; unsigned char hash1[32]; int i, c, len, output_interval; int hash_len; const BN_ULONG rekey_max = 10000000; BN_ULONG npoints, rekey_at, nbatch; vg_context_t *vcp = (vg_context_t *) arg; EC_KEY *pkey = NULL; const EC_GROUP *pgroup; const EC_POINT *pgen; const int ptarraysize = 256; EC_POINT *ppnt[ptarraysize]; EC_POINT *pbatchinc; vg_test_func_t test_func = vcp->vc_test; vg_exec_context_t ctx; vg_exec_context_t *vxcp; struct timeval tvstart; memset(&ctx, 0, sizeof(ctx)); vxcp = &ctx; vg_exec_context_init(vcp, &ctx); pkey = vxcp->vxc_key; pgroup = EC_KEY_get0_group(pkey); pgen = EC_GROUP_get0_generator(pgroup); for (i = 0; i < ptarraysize; i++) { ppnt[i] = EC_POINT_new(pgroup); if (!ppnt[i]) { fprintf(stderr, "ERROR: out of memory?\n"); exit(1); } } pbatchinc = EC_POINT_new(pgroup); if (!pbatchinc) { fprintf(stderr, "ERROR: out of memory?\n"); exit(1); } BN_set_word(&vxcp->vxc_bntmp, ptarraysize); EC_POINT_mul(pgroup, pbatchinc, &vxcp->vxc_bntmp, NULL, NULL, vxcp->vxc_bnctx); EC_POINT_make_affine(pgroup, pbatchinc, vxcp->vxc_bnctx); npoints = 0; rekey_at = 0; nbatch = 0; vxcp->vxc_key = pkey; vxcp->vxc_binres[0] = vcp->vc_addrtype; c = 0; output_interval = 1000; gettimeofday(&tvstart, NULL); if (vcp->vc_format == VCF_SCRIPT) { hash_buf[ 0] = 0x51; // OP_1 hash_buf[ 1] = 0x41; // pubkey length // gap for pubkey hash_buf[67] = 0x51; // OP_1 hash_buf[68] = 0xae; // OP_CHECKMULTISIG eckey_buf = hash_buf + 2; hash_len = 69; } else { eckey_buf = hash_buf; hash_len = (vcp->vc_compressed)?33:65; } while (!vcp->vc_halt) { if (++npoints >= rekey_at) { vg_exec_context_upgrade_lock(vxcp); /* Generate a new random private key */ EC_KEY_generate_key(pkey); npoints = 0; /* Determine rekey interval */ EC_GROUP_get_order(pgroup, &vxcp->vxc_bntmp, vxcp->vxc_bnctx); BN_sub(&vxcp->vxc_bntmp2, &vxcp->vxc_bntmp, EC_KEY_get0_private_key(pkey)); rekey_at = BN_get_word(&vxcp->vxc_bntmp2); if ((rekey_at == BN_MASK2) || (rekey_at > rekey_max)) rekey_at = rekey_max; assert(rekey_at > 0); EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey)); vg_exec_context_downgrade_lock(vxcp); npoints++; vxcp->vxc_delta = 0; if (vcp->vc_pubkey_base) EC_POINT_add(pgroup, ppnt[0], ppnt[0], vcp->vc_pubkey_base, vxcp->vxc_bnctx); for (nbatch = 1; (nbatch < ptarraysize) && (npoints < rekey_at); nbatch++, npoints++) { EC_POINT_add(pgroup, ppnt[nbatch], ppnt[nbatch-1], pgen, vxcp->vxc_bnctx); } } else { /* * Common case * * EC_POINT_add() can skip a few multiplies if * one or both inputs are affine (Z_is_one). * This is the case for every point in ppnt, as * well as pbatchinc. */ assert(nbatch == ptarraysize); for (nbatch = 0; (nbatch < ptarraysize) && (npoints < rekey_at); nbatch++, npoints++) { EC_POINT_add(pgroup, ppnt[nbatch], ppnt[nbatch], pbatchinc, vxcp->vxc_bnctx); } } /* * The single most expensive operation performed in this * loop is modular inversion of ppnt->Z. There is an * algorithm implemented in OpenSSL to do batched inversion * that only does one actual BN_mod_inverse(), and saves * a _lot_ of time. * * To take advantage of this, we batch up a few points, * and feed them to EC_POINTs_make_affine() below. */ EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx); for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) { /* Hash the public key */ len = EC_POINT_point2oct(pgroup, ppnt[i], (vcp->vc_compressed)?POINT_CONVERSION_COMPRESSED:POINT_CONVERSION_UNCOMPRESSED, eckey_buf, (vcp->vc_compressed)?33:65, vxcp->vxc_bnctx); assert(len == (vcp->vc_compressed)?33:65); SHA256(hash_buf, hash_len, hash1); RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]); switch (test_func(vxcp)) { case 1: npoints = 0; rekey_at = 0; i = nbatch; break; case 2: goto out; default: break; } } c += i; if (c >= output_interval) { output_interval = vg_output_timing(vcp, c, &tvstart); if (output_interval > 250000) output_interval = 250000; c = 0; } vg_exec_context_yield(vxcp); } out: vg_exec_context_del(&ctx); vg_context_thread_exit(vcp); for (i = 0; i < ptarraysize; i++) if (ppnt[i]) EC_POINT_free(ppnt[i]); if (pbatchinc) EC_POINT_free(pbatchinc); return NULL; }
static int input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; EC_POINT *client_public; EC_KEY *server_key = NULL; const EC_GROUP *group; const EC_POINT *public_key; BIGNUM *shared_secret = NULL; struct sshkey *server_host_private, *server_host_public; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t slen, sbloblen; size_t klen = 0, hashlen; int r; if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (EC_KEY_generate_key(server_key) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } group = EC_KEY_get0_group(server_key); #ifdef DEBUG_KEXECDH fputs("server private key:\n", stderr); sshkey_dump_ec_key(server_key); #endif if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } if ((client_public = EC_POINT_new(group)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXECDH fputs("client public key:\n", stderr); sshkey_dump_ec_point(group, client_public); #endif if (sshkey_ec_validate_public(group, client_public) != 0) { sshpkt_disconnect(ssh, "invalid client public key"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } /* Calculate shared_secret */ klen = (EC_GROUP_get_degree(group) + 7) / 8; if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (ECDH_compute_key(kbuf, klen, client_public, server_key, NULL) != (int)klen || BN_bin2bn(kbuf, klen, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif /* calc H */ if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; hashlen = sizeof(hash); if ((r = kex_ecdh_hash( kex->hash_alg, group, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, client_public, EC_KEY_get0_public_key(server_key), shared_secret, hash, &hashlen)) != 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ public_key = EC_KEY_get0_public_key(server_key); /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_ec(ssh, public_key, group)) != 0 || (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); if (kex->ec_client_key) { EC_KEY_free(kex->ec_client_key); kex->ec_client_key = NULL; } if (server_key) EC_KEY_free(server_key); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); free(server_host_key_blob); free(signature); return r; }
int main(int argc, char **argv) { int r, i; KDF_FUNC kdf = NULL; EC_GROUP *ec_group = NULL; EC_KEY *ec_key = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY *pub_key = NULL; EVP_PKEY *priv_key = NULL; X509_ALGOR *map = NULL; CPK_MASTER_SECRET *master = NULL; CPK_PUBLIC_PARAMS *params = NULL; BIO *bio_out = NULL; unsigned char *buf = NULL; unsigned char *p; const unsigned char *cp; int len; /* init openssl global functions */ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); /* prepare cpk setup parameters */ ec_key = EC_KEY_new_by_curve_name(OBJ_sn2nid("prime192v1")); assert(ec_key != NULL); EC_GROUP_set_asn1_flag((EC_GROUP *)EC_KEY_get0_group(ec_key), OPENSSL_EC_NAMED_CURVE); r = EC_KEY_generate_key(ec_key); assert(r == 1); pkey = EVP_PKEY_new(); assert(pkey != NULL); r = EVP_PKEY_set1_EC_KEY(pkey, ec_key); assert(r == 1); map = CPK_MAP_new_default(); assert(map != NULL); //EVP_PKEY_print_fp(pkey, stdout); /* generate master_secret and public_params */ master = CPK_MASTER_SECRET_create("domainid", pkey, map); OPENSSL_assert(master); bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); OPENSSL_assert(bio_out); r = CPK_MASTER_SECRET_print(bio_out, master, 0, 0); assert(r == 1); EVP_PKEY_free(pkey); pkey = NULL; pkey = CPK_MASTER_SECRET_extract_private_key(master, "id"); assert(pkey != NULL); EVP_PKEY_free(pkey); //pkey = CPK_MASTER_SECRET_extract_private_key(master, NULL); //assert(pkey == NULL); pkey = CPK_MASTER_SECRET_extract_private_key(master, id_long); assert(pkey != NULL); printf("EVP_PKEY of '%s':\n", id_long); EVP_PKEY_print_fp(pkey, stdout); printf("\n"); params = CPK_MASTER_SECRET_extract_public_params(master); assert(params); r = CPK_PUBLIC_PARAMS_print(bio_out, params, 0, 0); assert(r == 1); printf("\n"); printf("test CPK_PUBLIC_PARAMS_extract_public_key()\n"); pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_short); assert(pub_key != NULL); EVP_PKEY_free(pub_key); pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_long); assert(pub_key != NULL); printf("Public Key of '%s':\n", id_long); EVP_PKEY_print_fp(pkey, stdout); printf("\n"); r = CPK_MASTER_SECRET_validate_public_params(master, params); assert(r == 1); if (priv_key) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "identity"); assert(priv_key); r = CPK_PUBLIC_PARAMS_validate_private_key(params, "identity", priv_key); assert(r == 1); r = CPK_PUBLIC_PARAMS_validate_private_key(params, "id", priv_key); assert(r == 0); /* der encoding and decoding */ len = i2d_CPK_MASTER_SECRET(master, NULL); assert(len > 0); if (buf != NULL) OPENSSL_free(buf); buf = OPENSSL_malloc(len); assert(buf != NULL); p = buf; len = i2d_CPK_MASTER_SECRET(master, &p); assert(len > 0); assert(p - buf == len); cp = buf; if (master) CPK_MASTER_SECRET_free(master); master = NULL; master = d2i_CPK_MASTER_SECRET(NULL, &cp, len); assert(master != NULL); r = CPK_MASTER_SECRET_validate_public_params(master, params); assert(r == 1); kdf = KDF_get_x9_63(EVP_sha1()); assert(kdf != NULL); if (priv_key != NULL) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Alice"); assert(priv_key != NULL); if (buf != NULL) OPENSSL_free(buf); buf = OPENSSL_malloc(1024); assert(buf != NULL); r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Bob", priv_key, kdf); for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n"); if (priv_key != NULL) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Bob"); assert(priv_key != NULL); r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Alice", priv_key, kdf); for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n"); printf("ok\n"); return 0; }
int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, const ECDSA_SIG *sig, const EC_KEY *eckey) { int ret = 0; BN_CTX *ctx; BIGNUM *u1, *u2, *m, *X; EC_POINT *point = NULL; const EC_GROUP *group; const EC_POINT *pub_key; /* check input values */ if ((group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS); return 0; } ctx = BN_CTX_new(); if (!ctx) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); return 0; } BN_CTX_start(ctx); u1 = BN_CTX_get(ctx); u2 = BN_CTX_get(ctx); m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } const BIGNUM *order = EC_GROUP_get0_order(group); if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); goto err; } /* calculate tmp1 = inv(S) mod order */ int no_inverse; if (!BN_mod_inverse_odd(u2, &no_inverse, sig->s, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } if (!digest_to_bn(m, digest, digest_len, order)) { goto err; } /* u1 = m * tmp mod order */ if (!BN_mod_mul(u1, m, u2, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } /* u2 = r * w mod q */ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } point = EC_POINT_new(group); if (point == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } if (!BN_nnmod(u1, X, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } /* if the signature is correct u1 is equal to sig->r */ if (BN_ucmp(u1, sig->r) != 0) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); goto err; } ret = 1; err: BN_CTX_end(ctx); BN_CTX_free(ctx); EC_POINT_free(point); return ret; }
/* * Verifies gost 2001 signature * */ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, DSA_SIG *sig, EC_KEY *ec) { BN_CTX *ctx=BN_CTX_new(); const EC_GROUP *group = EC_KEY_get0_group(ec); BIGNUM *order; BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL; BIGNUM *X=NULL,*tmp=NULL; EC_POINT *C = NULL; const EC_POINT *pub_key=NULL; int ok=0; BN_CTX_start(ctx); order = BN_CTX_get(ctx); e = BN_CTX_get(ctx); z1 = BN_CTX_get(ctx); z2 = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); X= BN_CTX_get(ctx); R=BN_CTX_get(ctx); v=BN_CTX_get(ctx); EC_GROUP_get_order(group,order,ctx); pub_key = EC_KEY_get0_public_key(ec); if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || (BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); goto err; } md = hashsum2bn(dgst); BN_mod(e,md,order,ctx); #ifdef DEBUG_SIGN TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"digest as bignum: "); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,md); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\ndigest mod q: "); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,e); #endif if (BN_is_zero(e)) BN_one(e); v=BN_mod_inverse(v,e,order,ctx); BN_mod_mul(z1,sig->s,v,order,ctx); BN_sub(tmp,order,sig->r); BN_mod_mul(z2,tmp,v,order,ctx); #ifdef DEBUG_SIGN TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nInverted digest value: "); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,v); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nz1: "); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,z1); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nz2: "); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,z2); #endif C = EC_POINT_new(group); if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; } BN_mod(R,X,order,ctx); #ifdef DEBUG_SIGN TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nX="); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,X); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nX mod q="); BN_print_fp(OPENSSL_TYPE__FILE_STDERR,R); TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\n"); #endif if (BN_cmp(R,sig->r)!=0) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); } else { ok = 1; } err: EC_POINT_free(C); BN_CTX_end(ctx); BN_CTX_free(ctx); BN_free(md); return ok; }
static int ecdsa_sign_setup(const EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp, const uint8_t *digest, size_t digest_len) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *kinv = NULL, *r = NULL, *tmp = NULL; EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); return 0; } } else { ctx = ctx_in; } k = BN_new(); kinv = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ tmp = BN_new(); if (k == NULL || kinv == NULL || r == NULL || tmp == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } tmp_point = EC_POINT_new(group); if (tmp_point == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } const BIGNUM *order = EC_GROUP_get0_order(group); /* Check that the size of the group order is FIPS compliant (FIPS 186-4 * B.5.2). */ if (BN_num_bits(order) < 160) { OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER); goto err; } do { /* If possible, we'll include the private key and message digest in the k * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is * being used. */ if (eckey->fixed_k != NULL) { if (!BN_copy(k, eckey->fixed_k)) { goto err; } } else if (digest_len > 0) { do { if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey), digest, digest_len, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } } while (BN_is_zero(k)); } else if (!BN_rand_range_ex(k, 1, order)) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } /* Compute the inverse of k. The order is a prime, so use Fermat's Little * Theorem. Note |ec_group_get_mont_data| may return NULL but * |bn_mod_inverse_prime| allows this. */ if (!bn_mod_inverse_prime(kinv, k, order, ctx, ec_group_get_mont_data(group))) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } /* We do not want timing information to leak the length of k, * so we compute G*k using an equivalent scalar of fixed * bit-length. */ if (!BN_add(k, k, order)) { goto err; } if (BN_num_bits(k) <= BN_num_bits(order)) { if (!BN_add(k, k, order)) { goto err; } } /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, tmp, NULL, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } if (!BN_nnmod(r, tmp, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* clear old values if necessary */ BN_clear_free(*rp); BN_clear_free(*kinvp); /* save the pre-computed values */ *rp = r; *kinvp = kinv; ret = 1; err: BN_clear_free(k); if (!ret) { BN_clear_free(kinv); BN_clear_free(r); } if (ctx_in == NULL) { BN_CTX_free(ctx); } EC_POINT_free(tmp_point); BN_clear_free(tmp); return ret; }
int ec_main(int argc, char **argv) { int ret = 1; EC_KEY *eckey = NULL; const EC_GROUP *group; int i, badops = 0; const EVP_CIPHER *enc = NULL; BIO *in = NULL, *out = NULL; int informat, outformat, text = 0, noout = 0; int pubin = 0, pubout = 0, param_out = 0; char *infile, *outfile, *prog, *engine; char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; int new_form = 0; int asn1_flag = OPENSSL_EC_NAMED_CURVE; int new_asn1_flag = 0; if (!load_config(bio_err, NULL)) goto end; engine = NULL; infile = NULL; outfile = NULL; informat = FORMAT_PEM; outformat = FORMAT_PEM; prog = argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv, "-inform") == 0) { if (--argc < 1) goto bad; informat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-outform") == 0) { if (--argc < 1) goto bad; outformat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-in") == 0) { if (--argc < 1) goto bad; infile = *(++argv); } else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-passin") == 0) { if (--argc < 1) goto bad; passargin = *(++argv); } else if (strcmp(*argv, "-passout") == 0) { if (--argc < 1) goto bad; passargout = *(++argv); } else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } else if (strcmp(*argv, "-noout") == 0) noout = 1; else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-conv_form") == 0) { if (--argc < 1) goto bad; ++argv; new_form = 1; if (strcmp(*argv, "compressed") == 0) form = POINT_CONVERSION_COMPRESSED; else if (strcmp(*argv, "uncompressed") == 0) form = POINT_CONVERSION_UNCOMPRESSED; else if (strcmp(*argv, "hybrid") == 0) form = POINT_CONVERSION_HYBRID; else goto bad; } else if (strcmp(*argv, "-param_enc") == 0) { if (--argc < 1) goto bad; ++argv; new_asn1_flag = 1; if (strcmp(*argv, "named_curve") == 0) asn1_flag = OPENSSL_EC_NAMED_CURVE; else if (strcmp(*argv, "explicit") == 0) asn1_flag = 0; else goto bad; } else if (strcmp(*argv, "-param_out") == 0) param_out = 1; else if (strcmp(*argv, "-pubin") == 0) pubin = 1; else if (strcmp(*argv, "-pubout") == 0) pubout = 1; else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - " "DER or PEM\n"); BIO_printf(bio_err, " -outform arg output format - " "DER or PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -passin arg input file pass " "phrase source\n"); BIO_printf(bio_err, " -out arg output file\n"); BIO_printf(bio_err, " -passout arg output file pass " "phrase source\n"); BIO_printf(bio_err, " -engine e use engine e, " "possibly a hardware device.\n"); BIO_printf(bio_err, " -des encrypt PEM output, " "instead of 'des' every other \n" " cipher " "supported by OpenSSL can be used\n"); BIO_printf(bio_err, " -text print the key\n"); BIO_printf(bio_err, " -noout don't print key out\n"); BIO_printf(bio_err, " -param_out print the elliptic " "curve parameters\n"); BIO_printf(bio_err, " -conv_form arg specifies the " "point conversion form \n"); BIO_printf(bio_err, " possible values:" " compressed\n"); BIO_printf(bio_err, " " " uncompressed (default)\n"); BIO_printf(bio_err, " " " hybrid\n"); BIO_printf(bio_err, " -param_enc arg specifies the way" " the ec parameters are encoded\n"); BIO_printf(bio_err, " in the asn1 der " "encoding\n"); BIO_printf(bio_err, " possible values:" " named_curve (default)\n"); BIO_printf(bio_err, " " "explicit\n"); goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } BIO_printf(bio_err, "read EC key\n"); if (informat == FORMAT_ASN1) { if (pubin) eckey = d2i_EC_PUBKEY_bio(in, NULL); else eckey = d2i_ECPrivateKey_bio(in, NULL); } else if (informat == FORMAT_PEM) { if (pubin) eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); else eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin); } else { BIO_printf(bio_err, "bad input format specified for key\n"); goto end; } if (eckey == NULL) { BIO_printf(bio_err, "unable to load Key\n"); ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } group = EC_KEY_get0_group(eckey); if (new_form) EC_KEY_set_conv_form(eckey, form); if (new_asn1_flag) EC_KEY_set_asn1_flag(eckey, asn1_flag); if (text) if (!EC_KEY_print(out, eckey, 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } if (noout) { ret = 0; goto end; } BIO_printf(bio_err, "writing EC key\n"); if (outformat == FORMAT_ASN1) { if (param_out) i = i2d_ECPKParameters_bio(out, group); else if (pubin || pubout) i = i2d_EC_PUBKEY_bio(out, eckey); else i = i2d_ECPrivateKey_bio(out, eckey); } else if (outformat == FORMAT_PEM) { if (param_out) i = PEM_write_bio_ECPKParameters(out, group); else if (pubin || pubout) i = PEM_write_bio_EC_PUBKEY(out, eckey); else i = PEM_write_bio_ECPrivateKey(out, eckey, enc, NULL, 0, NULL, passout); } else { BIO_printf(bio_err, "bad output format specified for " "outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write private key\n"); ERR_print_errors(bio_err); } else ret = 0; end: if (in) BIO_free(in); if (out) BIO_free_all(out); if (eckey) EC_KEY_free(eckey); free(passin); free(passout); return (ret); }
ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, const EC_KEY *eckey) { int ok = 0; BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL; const BIGNUM *ckinv; BN_CTX *ctx = NULL; const EC_GROUP *group; ECDSA_SIG *ret; const BIGNUM *priv_key; if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); return NULL; } group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); if (group == NULL || priv_key == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); return NULL; } ret = ECDSA_SIG_new(); if (!ret) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); return NULL; } s = ret->s; if ((ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } const BIGNUM *order = EC_GROUP_get0_order(group); if (!digest_to_bn(m, digest, digest_len, order)) { goto err; } for (;;) { if (in_kinv == NULL || in_r == NULL) { if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, digest, digest_len)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_ECDSA_LIB); goto err; } ckinv = kinv; } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } } if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } if (!BN_mod_add_quick(s, tmp, m, order)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } if (!BN_mod_mul(s, s, ckinv, order, ctx)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } if (BN_is_zero(s)) { /* if kinv and r have been supplied by the caller * don't to generate new kinv and r values */ if (in_kinv != NULL && in_r != NULL) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NEED_NEW_SETUP_VALUES); goto err; } } else { /* s != 0 => we have a valid signature */ break; } } ok = 1; err: if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } BN_CTX_free(ctx); BN_clear_free(m); BN_clear_free(tmp); BN_clear_free(kinv); return ret; }
CK_RV PKCS11_Objects_OpenSSL::GetAttributeValue(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { OBJECT_DATA* pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(pSessionCtx, hObject); if(pObj == NULL) return CKR_OBJECT_HANDLE_INVALID; if(pObj->Type == CertificateType) { CERT_DATA* pCertData = (CERT_DATA*)pObj->Data; X509* pCert = pCertData->cert; INT32 valLen = 0; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_CLASS: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(CKO_CERTIFICATE); break; case CKA_PRIVATE: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->privKeyData.key == NULL ? 0 : 1); valLen = sizeof(INT32); break; case CKA_VALUE_BITS: { *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->pubKeyData.size); valLen = sizeof(INT32); } break; case CKA_KEY_TYPE: { *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->pubKeyData.type); valLen = sizeof(UINT32); } break; case CKA_ISSUER: { char* name=X509_NAME_oneline(X509_get_issuer_name(pCert),NULL,0); valLen = TINYCLR_SSL_STRLEN(name) + 1; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; hal_strcpy_s((char*)pTemplate[i].pValue, valLen, name); OPENSSL_free(name); } break; case CKA_SUBJECT: { char* subject=X509_NAME_oneline(X509_get_subject_name(pCert),NULL,0); valLen = TINYCLR_SSL_STRLEN(subject) + 1; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; hal_strcpy_s((char*)pTemplate[i].pValue, valLen, subject); OPENSSL_free(subject); } break; case CKA_SERIAL_NUMBER: { ASN1_INTEGER* asn = X509_get_serialNumber(pCert); valLen = asn->length; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, asn->data, valLen); } break; case CKA_MECHANISM_TYPE: if(pCert->sig_alg != NULL) { int signature_nid; CK_MECHANISM_TYPE type = CKM_VENDOR_DEFINED; signature_nid = OBJ_obj2nid(pCert->sig_alg->algorithm); switch(signature_nid) { case NID_sha1WithRSA: case NID_sha1WithRSAEncryption: //szNid = "1.2.840.113549.1.1.5"; type = CKM_SHA1_RSA_PKCS; break; case NID_md5WithRSA: case NID_md5WithRSAEncryption: //szNid = "1.2.840.113549.1.1.4"; type = CKM_MD5_RSA_PKCS; break; case NID_sha256WithRSAEncryption: //szNid = "1.2.840.113549.1.1.11"; type = CKM_SHA256_RSA_PKCS; break; case NID_sha384WithRSAEncryption: //szNid = "1.2.840.113549.1.1.12"; type = CKM_SHA384_RSA_PKCS; break; case NID_sha512WithRSAEncryption: //szNid = "1.2.840.113549.1.1.13"; type = CKM_SHA512_RSA_PKCS; break; } valLen = sizeof(CK_MECHANISM_TYPE); *(CK_MECHANISM_TYPE*)pTemplate[i].pValue = SwapEndianIfBEc32(type); } break; case CKA_START_DATE: { DATE_TIME_INFO dti; ssl_get_ASN1_UTCTIME(X509_get_notBefore(pCert), &dti); valLen = (INT32)pTemplate[i].ulValueLen; if(valLen > sizeof(dti)) valLen = sizeof(dti); TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, &dti, valLen); } break; case CKA_END_DATE: { DATE_TIME_INFO dti; ssl_get_ASN1_UTCTIME(X509_get_notAfter(pCert), &dti); valLen = pTemplate[i].ulValueLen; if(valLen > sizeof(dti)) valLen = sizeof(dti); TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, &dti, valLen); } break; case CKA_VALUE: { UINT8* pData = (UINT8*)pTemplate[i].pValue; UINT8* pTmp = pData; valLen = i2d_X509(pCert, NULL); if(valLen > pTemplate[i].ulValueLen) return CKR_DEVICE_MEMORY; valLen = i2d_X509(pCert, &pTmp); if(valLen < 0) return CKR_FUNCTION_FAILED; } break; case CKA_VALUE_LEN: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(valLen); break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } } else if(pObj->Type == KeyType) { KEY_DATA* pKey = (KEY_DATA*)pObj->Data; int valLen = 0; bool isPrivate = false; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_CLASS: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32((0 != (pKey->attrib & Private) ? CKO_PRIVATE_KEY : 0 != (pKey->attrib & Public) ? CKO_PUBLIC_KEY : CKO_SECRET_KEY)); break; case CKA_MODULUS: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->n, (UINT8*)pTemplate[i].pValue); } break; case CKA_EXPONENT_1: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->dmp1, (UINT8*)pTemplate[i].pValue); } break; case CKA_EXPONENT_2: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->dmq1, (UINT8*)pTemplate[i].pValue); } break; case CKA_COEFFICIENT: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->iqmp, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME_1: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->p, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME_2: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->q, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIVATE_EXPONENT: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->priv_key, (UINT8*)pTemplate[i].pValue); } else if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->d, (UINT8*)pTemplate[i].pValue); } break; case CKA_PUBLIC_EXPONENT: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->pub_key, (UINT8*)pTemplate[i].pValue); } else if(pKey->type == CKK_EC) { UINT8 pTmp[66*2+1]; EC_KEY* pEC = ((EVP_PKEY*)pKey->key)->pkey.ec; const EC_POINT* point = EC_KEY_get0_public_key(pEC); valLen = EC_POINT_point2oct(EC_KEY_get0_group(pEC), point, POINT_CONVERSION_UNCOMPRESSED, (UINT8*)pTmp, ARRAYSIZE(pTmp), NULL); if(valLen == 0) return CKR_FUNCTION_FAILED; memmove(pTemplate[i].pValue, &pTmp[1], valLen-1); // remove POINT_CONVERSION_UNCOMPRESSED header byte } else if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->e, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->p, (UINT8*)pTemplate[i].pValue); } break; case CKA_SUBPRIME: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->q, (UINT8*)pTemplate[i].pValue); } break; case CKA_BASE: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->g, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIVATE: isPrivate = 0 != *(INT32*)pTemplate[i].pValue; break; case CKA_KEY_TYPE: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pKey->type); break; case CKA_VALUE_BITS: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pKey->size); break; case CKA_VALUE: switch(pKey->type) { case CKK_AES: case CKK_GENERIC_SECRET: { // TODO: Add permissions to export key int len = (pKey->size + 7) / 8; if(len > (INT32)pTemplate[i].ulValueLen) len = (int)pTemplate[i].ulValueLen; TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, pKey->key, len); valLen = len; } break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } break; case CKA_VALUE_LEN: switch(pKey->type) { case CKK_EC: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(valLen); break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } } return CKR_OK; }
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) { unsigned char *buffer=NULL; size_t buf_len=0, i; int ret=0, reason=ERR_R_BIO_LIB; BIGNUM *pub_key=NULL, *order=NULL; BN_CTX *ctx=NULL; const EC_GROUP *group; const EC_POINT *public_key; const BIGNUM *priv_key; if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } public_key = EC_KEY_get0_public_key(x); if ((pub_key = EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { reason = ERR_R_EC_LIB; goto err; } buf_len = (size_t)BN_num_bytes(pub_key); priv_key = EC_KEY_get0_private_key(x); if (priv_key != NULL) { if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len) buf_len = i; } buf_len += 10; if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } if (priv_key != NULL) { if (!BIO_indent(bp, off, 128)) goto err; if ((order = BN_new()) == NULL) goto err; if (!EC_GROUP_get_order(group, order, NULL)) goto err; if (BIO_printf(bp, "Private-Key: (%d bit)\n", BN_num_bits(order)) <= 0) goto err; } if ((priv_key != NULL) && !print(bp, "priv:", priv_key, buffer, off)) goto err; if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, buffer, off)) goto err; if (!ECPKParameters_print(bp, group, off)) goto err; ret=1; err: if (!ret) ECerr(EC_F_EC_KEY_PRINT, reason); if (pub_key) BN_free(pub_key); if (order) BN_free(order); if (ctx) BN_CTX_free(ctx); if (buffer != NULL) OPENSSL_free(buffer); return(ret); }