/* * Computes 256 bit Key exchange key as specified in RFC 4357 */ static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk, unsigned char *shared_key) { unsigned char dh_key[128]; int ret; gost_hash_ctx hash_ctx; DH *dh = DH_new(); if (!dh) return 0; memset(dh_key, 0, 128); dh->g = BN_dup(pubk->pkey.dsa->g); dh->p = BN_dup(pubk->pkey.dsa->p); dh->priv_key = BN_dup(priv_key); ret = compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key, dh); DH_free(dh); if (!ret) return 0; init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet); start_hash(&hash_ctx); hash_block(&hash_ctx, dh_key, 128); finish_hash(&hash_ctx, shared_key); done_gost_hash_ctx(&hash_ctx); return 1; }
/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ static int VKO_compute_key (unsigned char *shared_key, size_t shared_key_size, const EC_POINT * pub_key, EC_KEY * priv_key, const unsigned char *ukm) { unsigned char ukm_be[8], databuf[64], hashbuf[64]; BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; const BIGNUM *key = EC_KEY_get0_private_key (priv_key); EC_POINT *pnt = EC_POINT_new (EC_KEY_get0_group (priv_key)); int i; gost_hash_ctx hash_ctx; BN_CTX *ctx = BN_CTX_new (); for (i = 0; i < 8; i++) { ukm_be[7 - i] = ukm[i]; } BN_CTX_start (ctx); UKM = getbnfrombuf (ukm_be, 8); p = BN_CTX_get (ctx); order = BN_CTX_get (ctx); X = BN_CTX_get (ctx); Y = BN_CTX_get (ctx); EC_GROUP_get_order (EC_KEY_get0_group (priv_key), order, ctx); BN_mod_mul (p, key, UKM, order, ctx); EC_POINT_mul (EC_KEY_get0_group (priv_key), pnt, NULL, pub_key, p, ctx); EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group (priv_key), pnt, X, Y, ctx); /*Serialize elliptic curve point same way as we do it when saving * key */ store_bignum (Y, databuf, 32); store_bignum (X, databuf + 32, 32); /* And reverse byte order of whole buffer */ for (i = 0; i < 64; i++) { hashbuf[63 - i] = databuf[i]; } init_gost_hash_ctx (&hash_ctx, &GostR3411_94_CryptoProParamSet); start_hash (&hash_ctx); hash_block (&hash_ctx, hashbuf, 64); finish_hash (&hash_ctx, shared_key); done_gost_hash_ctx (&hash_ctx); BN_free (UKM); BN_CTX_end (ctx); BN_CTX_free (ctx); EC_POINT_free (pnt); return 32; }
int main (int argc, char **argv) { int c, i; int verbose = 0; int errors = 0; int open_mode = O_RDONLY; gost_subst_block *b = &GostR3411_94_CryptoProParamSet; FILE *check_file = NULL; gost_hash_ctx ctx; while ((c = getopt (argc, argv, "bc::tv")) != -1) { switch (c) { case 'v': verbose = 1; break; case 't': b = &GostR3411_94_TestParamSet; break; case 'b': open_mode |= O_BINARY; break; case 'c': if (optarg) { check_file = fopen (optarg, "r"); if (!check_file) { perror (optarg); exit (2); } } else { check_file = stdin; } break; default: fprintf (stderr, "invalid option %c", optopt); help (); } } init_gost_hash_ctx (&ctx, b); if (check_file) { char inhash[65], calcsum[65], filename[PATH_MAX]; int failcount = 0, count = 0;; if (check_file == stdin && optind < argc) { check_file = fopen (argv[optind], "r"); if (!check_file) { perror (argv[optind]); exit (2); } } while (get_line (check_file, inhash, filename)) { if (!hash_file (&ctx, filename, calcsum, open_mode)) { exit (2); } count++; if (!strncmp (calcsum, inhash, 65)) { if (verbose) { fprintf (stderr, "%s\tOK\n", filename); } } else { if (verbose) { fprintf (stderr, "%s\tFAILED\n", filename); } else { fprintf (stderr, "%s: GOST hash sum check failed for '%s'\n", argv[0], filename); } failcount++; } } if (verbose && failcount) { fprintf (stderr, "%s: %d of %d file(f) failed GOST hash sum check\n", argv[0], failcount, count); } exit (failcount ? 1 : 0); } if (optind == argc) { char sum[65]; if (!hash_stream (&ctx, fileno (stdin), sum)) { perror ("stdin"); exit (1); } printf ("%s -\n", sum); exit (0); } for (i = optind; i < argc; i++) { char sum[65]; if (!hash_file (&ctx, argv[i], sum, open_mode)) { errors++; } else { printf ("%s %s\n", sum, argv[i]); } } exit (errors ? 1 : 0); }
int main(int argc,char **argv) { int c,i; int verbose=0; int errors=0; int open_mode = O_RDONLY; gost_subst_block *b= &GostR3411_94_CryptoProParamSet; TINYCLR_SSL_FILE *check_file = NULL; gost_hash_ctx ctx; while( (c=getopt(argc,argv,"bc::tv"))!=-1) { switch (c) { case 'v': verbose=1; break; case 't': b= &GostR3411_94_TestParamSet; break; case 'b': open_mode |= O_BINARY; break; case 'c': if (optarg) { check_file = TINYCLR_SSL_FOPEN(optarg,"r"); if (!check_file) { TINYCLR_SSL_PERROR(optarg); TINYCLR_SSL_EXIT(2); } } else { check_file= OPENSSL_TYPE__FILE_STDIN; } break; default: TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"invalid option %c",optopt); help(); } } init_gost_hash_ctx(&ctx,b); if (check_file) { char inhash[65],calcsum[65],filename[PATH_MAX]; int failcount=0,count=0;; if (check_file==OPENSSL_TYPE__FILE_STDIN && optind<argc) { check_file=TINYCLR_SSL_FOPEN(argv[optind],"r"); if (!check_file) { TINYCLR_SSL_PERROR(argv[optind]); TINYCLR_SSL_EXIT(2); } } while (get_line(check_file,inhash,filename)) { if (!hash_file(&ctx,filename,calcsum,open_mode)) { TINYCLR_SSL_EXIT (2); } count++; if (!TINYCLR_SSL_STRNCMP(calcsum,inhash,65)) { if (verbose) { TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"%s\tOK\n",filename); } } else { if (verbose) { TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"%s\tFAILED\n",filename); } else { TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"%s: GOST hash sum check failed for '%s'\n", argv[0],filename); } failcount++; } } if (verbose && failcount) { TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"%s: %d of %d file(f) failed GOST hash sum check\n", argv[0],failcount,count); } TINYCLR_SSL_EXIT (failcount?1:0); } if (optind==argc) { char sum[65]; if (!hash_stream(&ctx,TINYCLR_SSL_FILENO(OPENSSL_TYPE__FILE_STDIN),sum)) { TINYCLR_SSL_PERROR("OPENSSL_TYPE__FILE_STDIN"); TINYCLR_SSL_EXIT(1); } TINYCLR_SSL_PRINTF("%s -\n",sum); TINYCLR_SSL_EXIT(0); } for (i=optind;i<argc;i++) { char sum[65]; if (!hash_file(&ctx,argv[i],sum,open_mode)) { errors++; } else { TINYCLR_SSL_PRINTF("%s %s\n",sum,argv[i]); } } TINYCLR_SSL_EXIT(errors?1:0); }