/* Test the public key sign function using the private ket SKEY. PKEY is used for verification. */ static void check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; int dataidx; static const char baddata[] = "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n"; static struct { const char *data; int expected_rc; } datas[] = { { "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0 }, { "(data\n (flags )\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1)\n" " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n", GPG_ERR_DIGEST_ALGO }, { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", 0 }, { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", 0 }, { "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", GPG_ERR_CONFLICT }, { "(data\n (flags raw foo)\n" " (value #11223344556677889900AA#))\n", GPG_ERR_INV_FLAG }, { NULL } }; rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); for (dataidx = 0; datas[dataidx].data; dataidx++) { if (verbose) fprintf (stderr, "signature test %d\n", dataidx); rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_sign (&sig, hash, skey); if (gcry_err_code (rc) != datas[dataidx].expected_rc) fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); if (!rc) verify_one_signature (pkey, hash, badhash, sig); gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (hash); hash = NULL; } gcry_sexp_release (badhash); }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, const unsigned char *hash, unsigned long hash_len, unsigned char *sig) { unsigned char zhash[SHA_DIGEST_LENGTH + 1]; gcry_sexp_t sig_sexp; gcry_sexp_t data; int ret; const char *tmp; size_t size; if (hash_len != SHA_DIGEST_LENGTH) { return -1; } memcpy(zhash + 1, hash, hash_len); zhash[0] = 0; if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) { return -1; } ret = gcry_pk_sign(&sig_sexp, data, dsactx); gcry_sexp_release(data); if (ret != 0) { return -1; } memset(sig, 0, 40); /* Extract R. */ data = gcry_sexp_find_token(sig_sexp, "r", 0); if (!data) goto err; tmp = gcry_sexp_nth_data(data, 1, &size); if (!tmp) goto err; if (tmp[0] == '\0') { tmp++; size--; } if (size < 1 || size > 20) goto err; memcpy(sig + (20 - size), tmp, size); gcry_sexp_release(data); /* Extract S. */ data = gcry_sexp_find_token(sig_sexp, "s", 0); if (!data) goto err; tmp = gcry_sexp_nth_data(data, 1, &size); if (!tmp) goto err; if (tmp[0] == '\0') { tmp++; size--; } if (size < 1 || size > 20) goto err; memcpy(sig + 20 + (20 - size), tmp, size); goto out; err: ret = -1; out: if (sig_sexp) { gcry_sexp_release(sig_sexp); } if (data) { gcry_sexp_release(data); } return ret; }
/* this function signs the session id */ STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey) { CRYPTO *crypto=session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; STRING *signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t data_sexp; #endif ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } switch(privatekey->type) { case TYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, data_sexp, privatekey->dsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa_priv); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case TYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, data_sexp, privatekey->rsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa_priv); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(data_sexp); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }
/* Check against PKCS#1 v1.5 signature test vectors as found at ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt . */ static void check_v15sign (void) { #include "pkcs1v2-v15s.h" gpg_error_t err; int tno, mno; for (tno = 0; tno < DIM (tbl); tno++) { void *rsa_n, *rsa_e, *rsa_d; size_t rsa_n_len, rsa_e_len, rsa_d_len; gcry_sexp_t sec_key, pub_key; if (verbose > 1) info ("(%s)\n", tbl[tno].desc); rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len); rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len); rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len); err = gcry_sexp_build (&sec_key, NULL, "(private-key (rsa (n %b)(e %b)(d %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e, (int)rsa_d_len, rsa_d); if (err) die ("constructing private key failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&pub_key, NULL, "(public-key (rsa (n %b)(e %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e); if (err) die ("constructing public key failed: %s\n", gpg_strerror (err)); gcry_free (rsa_n); gcry_free (rsa_e); gcry_free (rsa_d); for (mno = 0; mno < DIM (tbl[0].m); mno++) { void *mesg, *sign; size_t mesg_len, sign_len; gcry_sexp_t sigtmpl, sig; char mhash[20]; if (verbose) info ("running test: %s\n", tbl[tno].m[mno].desc); mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pkcs1)" "(hash sha1 %b))", 20, mhash); if (err) die ("constructing sig template failed: %s\n", gpg_strerror (err)); gcry_free (mesg); err = gcry_pk_sign (&sig, sigtmpl, sec_key); if (err) { show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, tbl[tno].m[mno].desc)) { show_sexp ("sign result:\n", sig); fail ("mismatch in gcry_pk_sign\n"); } gcry_sexp_release (sig); sig = NULL; } gcry_sexp_release (sigtmpl); sigtmpl = NULL; /* Now test the verification. */ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len); err = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s %b)))", (int)sign_len, sign); if (err) die ("constructing verify data failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pkcs1)" "(hash sha1 %b))", 20, mhash); if (err) die ("constructing verify tmpl failed: %s\n", gpg_strerror (err)); gcry_free (sign); err = gcry_pk_verify (sig, sigtmpl, pub_key); if (err) { show_sexp ("sig:\n", sig); show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err)); } gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (sigtmpl); sigtmpl = NULL; } gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } }
static void one_test (int testno, const char *sk, const char *pk, const char *msg, const char *sig) { gpg_error_t err; int i; char *p; void *buffer = NULL; void *buffer2 = NULL; size_t buflen, buflen2; gcry_sexp_t s_tmp, s_tmp2; gcry_sexp_t s_sk = NULL; gcry_sexp_t s_pk = NULL; gcry_sexp_t s_msg= NULL; gcry_sexp_t s_sig= NULL; unsigned char *sig_r = NULL; unsigned char *sig_s = NULL; char *sig_rs_string = NULL; size_t sig_r_len, sig_s_len; if (verbose > 1) show ("Running test %d\n", testno); if (!(buffer = hex2buffer (sk, &buflen))) { fail ("error building s-exp for test %d, %s: %s", testno, "sk", "invalid hex string"); goto leave; } if (!(buffer2 = hex2buffer (pk, &buflen2))) { fail ("error building s-exp for test %d, %s: %s", testno, "pk", "invalid hex string"); goto leave; } if (sign_with_pk) err = gcry_sexp_build (&s_sk, NULL, "(private-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (q %b)" " (d %b)))", (int)buflen2, buffer2, (int)buflen, buffer); else err = gcry_sexp_build (&s_sk, NULL, "(private-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (d %b)))", (int)buflen, buffer); if (err) { fail ("error building s-exp for test %d, %s: %s", testno, "sk", gpg_strerror (err)); goto leave; } if ((err = gcry_sexp_build (&s_pk, NULL, "(public-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (q %b)))", (int)buflen2, buffer2))) { fail ("error building s-exp for test %d, %s: %s", testno, "pk", gpg_strerror (err)); goto leave; } xfree (buffer); if (!(buffer = hex2buffer (msg, &buflen))) { fail ("error building s-exp for test %d, %s: %s", testno, "msg", "invalid hex string"); goto leave; } if ((err = gcry_sexp_build (&s_msg, NULL, "(data" " (flags eddsa)" " (hash-algo sha512)" " (value %b))", (int)buflen, buffer))) { fail ("error building s-exp for test %d, %s: %s", testno, "msg", gpg_strerror (err)); goto leave; } if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); if (debug) show_sexp ("sig=", s_sig); s_tmp2 = NULL; s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); if (s_tmp) { s_tmp2 = s_tmp; s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0); if (s_tmp) { gcry_sexp_release (s_tmp2); s_tmp2 = s_tmp; s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0); if (s_tmp) { sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len); gcry_sexp_release (s_tmp); } s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0); if (s_tmp) { sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len); gcry_sexp_release (s_tmp); } } } gcry_sexp_release (s_tmp2); s_tmp2 = NULL; if (!sig_r || !sig_s) fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing"); else { sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1); p = sig_rs_string; *p = 0; for (i=0; i < sig_r_len; i++, p += 2) snprintf (p, 3, "%02x", sig_r[i]); for (i=0; i < sig_s_len; i++, p += 2) snprintf (p, 3, "%02x", sig_s[i]); if (strcmp (sig_rs_string, sig)) { fail ("gcry_pk_sign failed for test %d: %s", testno, "wrong value returned"); show (" expected: '%s'", sig); show (" got: '%s'", sig_rs_string); } } if (!no_verify) if ((err = gcry_pk_verify (s_sig, s_msg, s_pk))) fail ("gcry_pk_verify failed for test %d: %s", testno, gpg_strerror (err)); leave: gcry_sexp_release (s_sig); gcry_sexp_release (s_sk); gcry_sexp_release (s_pk); gcry_sexp_release (s_msg); xfree (buffer); xfree (buffer2); xfree (sig_r); xfree (sig_s); xfree (sig_rs_string); }
/* * This function signs the session id (known as H) as a string then * the content of sigbuf */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, ssh_key privatekey) { struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; ssh_string session_str = NULL; ssh_string signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t gcryhash; #endif if(privatekey == NULL || !ssh_key_is_private(privatekey)) { return NULL; } session_str = ssh_string_new(SHA_DIGEST_LEN); if (session_str == NULL) { return NULL; } ssh_string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN); ctx = sha1_init(); if (ctx == NULL) { ssh_string_free(session_str); return NULL; } sha1_update(ctx, session_str, ssh_string_len(session_str) + 4); ssh_string_free(session_str); sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } switch(privatekey->type) { case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, gcryhash, privatekey->dsa)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r", sign->dsa_sign->r); ssh_print_bignum("s", sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, gcryhash, privatekey->rsa)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; default: signature_free(sign); return NULL; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(gcryhash); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }
static void check_ed25519ecdsa_sample_key (void) { static const char ecc_private_key[] = "(private-key\n" " (ecc\n" " (curve \"Ed25519\")\n" " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321" " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)" " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)" "))"; static const char ecc_private_key_wo_q[] = "(private-key\n" " (ecc\n" " (curve \"Ed25519\")\n" " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)" "))"; static const char ecc_public_key[] = "(public-key\n" " (ecc\n" " (curve \"Ed25519\")\n" " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321" " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)" "))"; static const char ecc_public_key_comp[] = "(public-key\n" " (ecc\n" " (curve \"Ed25519\")\n" " (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)" "))"; static const char hash_string[] = "(data (flags ecdsa rfc6979)\n" " (hash sha256 #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))"; gpg_error_t err; gcry_sexp_t key, hash, sig; if (verbose) fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n"); /* Sign. */ if ((err = gcry_sexp_new (&hash, hash_string, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign failed: %s", gpg_strerror (err)); /* Verify. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify failed: %s", gpg_strerror (err)); /* Verify again using a compressed public key. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err)); /* Sign without a Q parameter. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); gcry_sexp_release (sig); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err)); /* Verify. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err)); /* Verify again using a compressed public key. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err)); extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4" "655d0179e22199bf63691fd88eb64e15")); extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185" "623ddaf5d02fa65ca5056cb6bd0f16f1")); gcry_sexp_release (sig); gcry_sexp_release (key); gcry_sexp_release (hash); }
static void check_ecc_sample_key (void) { static const char ecc_private_key[] = "(private-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781" "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)" "))"; static const char ecc_private_key_wo_q[] = "(private-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)" "))"; static const char ecc_public_key[] = "(public-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781" "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)" "))"; static const char hash_string[] = "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))"; gpg_error_t err; gcry_sexp_t key, hash, sig; if (verbose) fprintf (stderr, "Checking sample ECC key.\n"); if ((err = gcry_sexp_new (&hash, hash_string, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign failed: %s", gpg_strerror (err)); gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify failed: %s", gpg_strerror (err)); /* Now try signing without the Q parameter. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); gcry_sexp_release (sig); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err)); gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err)); gcry_sexp_release (sig); gcry_sexp_release (key); gcry_sexp_release (hash); }
static void ecc_bench (int iterations, int print_header) { #if USE_ECC gpg_error_t err; int p_sizes[] = { 192, 224, 256, 384, 521 }; int testno; if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) { gcry_sexp_t key_spec, key_pair, pub_key, sec_key; gcry_mpi_t x; gcry_sexp_t data; gcry_sexp_t sig = NULL; int count; printf ("ECDSA %3d bit ", p_sizes[testno]); fflush (stdout); err = gcry_sexp_build (&key_spec, NULL, "(genkey (ECDSA (nbits %d)))", p_sizes[testno]); if (err) die ("creating S-expression failed: %s\n", gcry_strerror (err)); start_timer (); err = gcry_pk_genkey (&key_pair, key_spec); if (err) die ("creating %d bit ECC key failed: %s\n", p_sizes[testno], gcry_strerror (err)); pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key_pair); gcry_sexp_release (key_spec); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed: %s\n", gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (count=0; count < iterations; count++) { err = gcry_pk_verify (sig, data, pub_key); if (err) { putchar ('\n'); show_sexp ("seckey:\n", sec_key); show_sexp ("data:\n", data); show_sexp ("sig:\n", sig); die ("verify failed: %s\n", gpg_strerror (err)); } } stop_timer (); printf (" %s\n", elapsed_time ()); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } #endif /*USE_ECC*/ }
static void dsa_bench (int iterations, int print_header) { gpg_error_t err; gcry_sexp_t pub_key[3], sec_key[3]; int p_sizes[3] = { 1024, 2048, 3072 }; int q_sizes[3] = { 160, 224, 256 }; gcry_sexp_t data; gcry_sexp_t sig; int i, j; err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024, strlen (sample_public_dsa_key_1024)); if (!err) err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024, strlen (sample_private_dsa_key_1024)); if (!err) err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048, strlen (sample_public_dsa_key_2048)); if (!err) err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048, strlen (sample_private_dsa_key_2048)); if (!err) err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072, strlen (sample_public_dsa_key_3072)); if (!err) err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072, strlen (sample_private_dsa_key_3072)); if (err) { fprintf (stderr, PGM ": converting sample keys failed: %s\n", gcry_strerror (err)); exit (1); } if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (i=0; i < DIM (q_sizes); i++) { gcry_mpi_t x; x = gcry_mpi_new (q_sizes[i]); gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) { fprintf (stderr, PGM ": converting data failed: %s\n", gcry_strerror (err)); exit (1); } printf ("DSA %d/%d -", p_sizes[i], q_sizes[i]); fflush (stdout); start_timer (); for (j=0; j < iterations; j++) { err = gcry_pk_sign (&sig, data, sec_key[i]); if (err) { putchar ('\n'); fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err)); exit (1); } } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (j=0; j < iterations; j++) { err = gcry_pk_verify (sig, data, pub_key[i]); if (err) { putchar ('\n'); fprintf (stderr, PGM ": verify failed: %s\n", gpg_strerror (err)); exit (1); } } stop_timer (); printf (" %s\n", elapsed_time ()); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); } for (i=0; i < DIM (q_sizes); i++) { gcry_sexp_release (sec_key[i]); gcry_sexp_release (pub_key[i]); } }
static void rsa_bench (int iterations, int print_header, int no_blinding) { gpg_error_t err; int p_sizes[] = { 1024, 2048, 3072, 4096 }; int testno; if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) { gcry_sexp_t key_spec, key_pair, pub_key, sec_key; gcry_mpi_t x; gcry_sexp_t data; gcry_sexp_t sig = NULL; int count; printf ("RSA %3d bit ", p_sizes[testno]); fflush (stdout); err = gcry_sexp_build (&key_spec, NULL, gcry_fips_mode_active () ? "(genkey (RSA (nbits %d)))" : "(genkey (RSA (nbits %d)(transient-key)))", p_sizes[testno]); if (err) die ("creating S-expression failed: %s\n", gcry_strerror (err)); start_timer (); err = gcry_pk_genkey (&key_pair, key_spec); if (err) die ("creating %d bit RSA key failed: %s\n", p_sizes[testno], gcry_strerror (err)); pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key_pair); gcry_sexp_release (key_spec); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed (%d): %s\n", count, gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (count=0; count < iterations; count++) { err = gcry_pk_verify (sig, data, pub_key); if (err) { putchar ('\n'); show_sexp ("seckey:\n", sec_key); show_sexp ("data:\n", data); show_sexp ("sig:\n", sig); die ("verify failed (%d): %s\n", count, gpg_strerror (err)); } } stop_timer (); printf (" %s", elapsed_time ()); if (no_blinding) { fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags no-blinding) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed (%d): %s\n", count, gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); } putchar ('\n'); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } }
/* this function signs the session id (known as H) as a string then the content of sigbuf */ STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf, PRIVATE_KEY *privatekey){ SHACTX ctx; STRING *session_str=string_new(SHA_DIGEST_LEN); unsigned char hash[SHA_DIGEST_LEN+1]; #ifdef HAVE_LIBGCRYPT gcry_sexp_t gcryhash; #endif SIGNATURE *sign; STRING *signature; CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto; string_fill(session_str,crypto->session_id,SHA_DIGEST_LEN); ctx=sha1_init(); sha1_update(ctx,session_str,string_len(session_str)+4); sha1_update(ctx,buffer_get(sigbuf),buffer_get_len(sigbuf)); sha1_final(hash+1,ctx); hash[0]=0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif free(session_str); sign=malloc(sizeof(SIGNATURE)); switch(privatekey->type){ case TYPE_DSS: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&gcryhash,NULL,"%b",SHA_DIGEST_LEN+1,hash); gcry_pk_sign(&sign->dsa_sign,gcryhash,privatekey->dsa_priv); #elif defined HAVE_LIBCRYPTO sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv); #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif sign->rsa_sign=NULL; break; case TYPE_RSA: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&gcryhash,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1); gcry_pk_sign(&sign->rsa_sign,gcryhash,privatekey->rsa_priv); #elif defined HAVE_LIBCRYPTO sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv); #endif sign->dsa_sign=NULL; break; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(gcryhash); #endif sign->type=privatekey->type; if(!sign->dsa_sign && !sign->rsa_sign){ #ifdef HAVE_LIBGCRYPT ssh_set_error(session,SSH_FATAL,"Signing : libcrypt error"); #elif HAVE_LIBCRYPTO ssh_set_error(session,SSH_FATAL,"Signing : openssl error"); #endif signature_free(sign); return NULL; } signature=signature_to_string(sign); signature_free(sign); return signature; }
/* in case of DSA puts into data, r,s */ static int _gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey, int pkey_len) { gcry_sexp_t s_hash, s_key, s_sig; int rc = -1; /* make a sexp from pkey */ switch (algo) { case GCRY_PK_DSA: if (pkey_len >= 5) rc = gcry_sexp_build (&s_key, NULL, "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]); else { gnutls_assert (); } break; case GCRY_PK_RSA: if (pkey_len >= 6) rc = gcry_sexp_build (&s_key, NULL, "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5]); else { gnutls_assert (); } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } if (rc != 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* put the data into a simple list */ if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* pass it to libgcrypt */ rc = gcry_pk_sign (&s_sig, s_hash, s_key); gcry_sexp_release (s_hash); gcry_sexp_release (s_key); if (rc != 0) { gnutls_assert (); return GNUTLS_E_PK_SIGN_FAILED; } else { gcry_sexp_t list; if (algo == GCRY_PK_DSA) { list = gcry_sexp_find_token (s_sig, "r", 0); if (list == NULL) { gnutls_assert (); gcry_sexp_release (s_sig); return GNUTLS_E_INTERNAL_ERROR; } data[0] = gcry_sexp_nth_mpi (list, 1, 0); gcry_sexp_release (list); list = gcry_sexp_find_token (s_sig, "s", 0); if (list == NULL) { gnutls_assert (); gcry_sexp_release (s_sig); return GNUTLS_E_INTERNAL_ERROR; } data[1] = gcry_sexp_nth_mpi (list, 1, 0); gcry_sexp_release (list); } else { /* GCRY_PK_RSA */ list = gcry_sexp_find_token (s_sig, "s", 0); if (list == NULL) { gnutls_assert (); gcry_sexp_release (s_sig); return GNUTLS_E_INTERNAL_ERROR; } data[0] = gcry_sexp_nth_mpi (list, 1, 0); gcry_sexp_release (list); } } gcry_sexp_release (s_sig); return 0; }