int R_VerifyFinal(R_SIGNATURE_CTX *ctx, uint8_t *signature, unsigned length, R_RSA_PUBLIC_KEY *key) { struct rsa_public_key k; int res; nettle_mpz_init_set_str_256_u(k.n, MAX_RSA_MODULUS_LEN, key->modulus); nettle_mpz_init_set_str_256_u(k.e, MAX_RSA_MODULUS_LEN, key->exponent); if (rsa_public_key_prepare(&k) && (k.size == length)) { mpz_t s; nettle_mpz_init_set_str_256_u(s, k.size, signature); res = rsa_md5_verify(&k, &ctx->hash, s) ? RE_SUCCESS : RE_SIGNATURE; mpz_clear(s); } else res = RE_PUBLIC_KEY; mpz_clear(k.n); mpz_clear(k.e); return res; }
int R_SignFinal(R_SIGNATURE_CTX *ctx, uint8_t *signature, unsigned *length, R_RSA_PRIVATE_KEY *key) { struct rsa_private_key k; int res; nettle_mpz_init_set_str_256_u(k.p, MAX_RSA_MODULUS_LEN, key->prime[0]); nettle_mpz_init_set_str_256_u(k.q, MAX_RSA_MODULUS_LEN, key->prime[1]); nettle_mpz_init_set_str_256_u(k.a, MAX_RSA_MODULUS_LEN, key->primeExponent[0]); nettle_mpz_init_set_str_256_u(k.b, MAX_RSA_MODULUS_LEN, key->primeExponent[1]); nettle_mpz_init_set_str_256_u(k.c, MAX_RSA_MODULUS_LEN, key->coefficient); if (rsa_private_key_prepare(&k) && (k.size <= MAX_RSA_MODULUS_LEN)) { mpz_t s; mpz_init(s); if (rsa_md5_sign(&k, &ctx->hash, s)) { nettle_mpz_get_str_256(k.size, signature, s); *length = k.size; res = RE_SUCCESS; } else res = RE_PRIVATE_KEY; mpz_clear(s); } else res = RE_PRIVATE_KEY; mpz_clear(k.p); mpz_clear(k.q); mpz_clear(k.a); mpz_clear(k.b); mpz_clear(k.c); return res; }
/* =============== SV_RSAGenMsg Generate an encrypted RSA message =============== */ int SV_RSAGenMsg( const char *pubkey, char *cleartext, char *encrypted ) { struct rsa_public_key public_key; mpz_t message; unsigned char buffer[ RSA_KEY_LENGTH / 8 - 11 ]; int retval; Com_RandomBytes( buffer, RSA_KEY_LENGTH / 8 - 11 ); nettle_mpz_init_set_str_256_u( message, RSA_KEY_LENGTH / 8 - 11, buffer ); mpz_get_str( cleartext, 16, message ); rsa_public_key_init( &public_key ); mpz_set_ui( public_key.e, RSA_PUBLIC_EXPONENT ); retval = mpz_set_str( public_key.n, pubkey, 16 ) + 1; if ( retval ) { rsa_public_key_prepare( &public_key ); retval = rsa_encrypt( &public_key, NULL, qnettle_random, RSA_KEY_LENGTH / 8 - 11, buffer, message ); } rsa_public_key_clear( &public_key ); mpz_get_str( encrypted, 16, message ); mpz_clear( message ); return retval; }
static void test_prime(const gnutls_datum_t * prime) { mpz_t p; unsigned bits = prime->size * 8; nettle_mpz_init_set_str_256_u(p, prime->size, prime->data); assert(mpz_sizeinbase(p, 2) == bits); assert(mpz_probab_prime_p(p, 18)); mpz_clear(p); }
static char * _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen) { int res = 0; struct ecc_point pubkey; struct dsa_signature signature; /* Always matched strength, as per RFC 6605 sec. 1 */ if (sigblock_len != 2*digest_size || keylen != 2*digest_size) { return "wrong ECDSA signature length"; } /* Parse ECDSA signature as per RFC 6605 sec. 4 */ nettle_dsa_signature_init(&signature); switch (digest_size) { case SHA256_DIGEST_SIZE: { uint8_t digest[SHA256_DIGEST_SIZE]; mpz_t x, y; nettle_ecc_point_init(&pubkey, &nettle_secp_256r1); nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key); nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE); nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock); nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE); res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= nettle_ecc_point_set(&pubkey, x, y); res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); mpz_clear(x); mpz_clear(y); break; } case SHA384_DIGEST_SIZE: { uint8_t digest[SHA384_DIGEST_SIZE]; mpz_t x, y; nettle_ecc_point_init(&pubkey, &nettle_secp_384r1); nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key); nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE); nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock); nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE); res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= nettle_ecc_point_set(&pubkey, x, y); res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature); mpz_clear(x); mpz_clear(y); nettle_ecc_point_clear(&pubkey); break; } default: return "unknown ECDSA algorithm"; } /* Clear and return */ nettle_dsa_signature_clear(&signature); if (!res) return "ECDSA signature verification failed"; else return NULL; }
static char * _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, unsigned int sigblock_len, uint8_t* key, unsigned int keylen) { uint16_t exp_len = 0; size_t exp_offset = 0, mod_offset = 0; struct rsa_public_key pubkey; mpz_t signature; int res = 0; /* RSA pubkey parsing as per RFC 3110 sec. 2 */ if( keylen <= 1) { return "null RSA key"; } if (key[0] != 0) { /* 1-byte length */ exp_len = key[0]; exp_offset = 1; } else { /* 1-byte NUL + 2-bytes exponent length */ if (keylen < 3) { return "incorrect RSA key length"; } exp_len = READ_UINT16(key+1); if (exp_len == 0) return "null RSA exponent length"; exp_offset = 3; } /* Check that we are not over-running input length */ if (keylen < exp_offset + exp_len + 1) { return "RSA key content shorter than expected"; } mod_offset = exp_offset + exp_len; nettle_rsa_public_key_init(&pubkey); pubkey.size = keylen - mod_offset; nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); switch (digest_size) { case SHA1_DIGEST_SIZE: { uint8_t digest[SHA1_DIGEST_SIZE]; res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha1_verify_digest(&pubkey, digest, signature); break; } case SHA256_DIGEST_SIZE: { uint8_t digest[SHA256_DIGEST_SIZE]; res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha256_verify_digest(&pubkey, digest, signature); break; } case SHA512_DIGEST_SIZE: { uint8_t digest[SHA512_DIGEST_SIZE]; res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha512_verify_digest(&pubkey, digest, signature); break; } default: break; } /* Clear and return */ nettle_rsa_public_key_clear(&pubkey); mpz_clear(signature); if (!res) { return "RSA signature verification failed"; } else { return NULL; } }