Exemple #1
0
Test::Result
PK_Signature_Verification_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));
   std::unique_ptr<Botan::Public_Key> pubkey = load_public_key(vars);

   Test::Result result(algo_name() + "/" + padding + " signature verification");

   for(auto&& verify_provider : possible_pk_providers())
      {
      std::unique_ptr<Botan::PK_Verifier> verifier;

      try
         {
         verifier.reset(new Botan::PK_Verifier(*pubkey, padding, Botan::IEEE_1363, verify_provider));
         result.test_eq("correct signature valid", verifier->verify_message(message, signature), true);
         check_invalid_signatures(result, *verifier, message, signature);
         }
      catch(Botan::Lookup_Error&)
         {
         result.test_note("Skipping verifying with " + verify_provider);
         }
      }

   return result;
   }
Exemple #2
0
Test::Result
PK_Signature_NonVerification_Test::run_one_test(const std::string& pad_hdr, const VarMap& vars)
   {
   const std::string padding = choose_padding(vars, pad_hdr);
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   std::unique_ptr<Botan::Public_Key> pubkey = load_public_key(vars);

   const std::vector<uint8_t> invalid_signature = get_req_bin(vars, "InvalidSignature");

   Test::Result result(algo_name() + "/" + padding + " verify invalid signature");

   for(auto const& verify_provider : possible_providers(algo_name()))
      {
      std::unique_ptr<Botan::PK_Verifier> verifier;

      try
         {
         verifier.reset(new Botan::PK_Verifier(*pubkey, padding, Botan::IEEE_1363, verify_provider));
         result.test_eq("incorrect signature rejected", verifier->verify_message(message, invalid_signature), false);
         }
      catch(Botan::Lookup_Error&)
         {
         result.test_note("Skipping verifying with " + verify_provider);
         }
      }

   return result;
   }
Exemple #3
0
Test::Result
PK_Signature_Verification_Test::run_one_test(const std::string&, const VarMap& vars)
   {
   const std::vector<uint8_t> message   = get_req_bin(vars, "Msg");
   const std::vector<uint8_t> signature = get_req_bin(vars, "Signature");
   const std::string padding = get_opt_str(vars, "Padding", default_padding(vars));
   std::unique_ptr<Botan::Public_Key> pubkey = load_public_key(vars);

   Test::Result result(algo_name() + "/" + padding + " signature verification");

   Botan::PK_Verifier verifier(*pubkey, padding);

   result.test_eq("correct signature valid", verifier.verify_message(message, signature), true);

   check_invalid_signatures(result, verifier, message, signature);

   return result;
   }
Exemple #4
0
/*
 *	Check the crypto signature on the image...
 *	This always includes a public key encrypted header and an MD5
 *	(or SHA256) checksum. It optionally includes AES encryption of
 *	the image.
 */
static int check_crypto_signature(void)
{
	struct header hdr;
	int hash_length;
	unsigned long fblength, length;
	unsigned char *data;
	RSA *pkey;
#ifdef CONFIG_USER_NETFLASH_CRYPTO_V2
	unsigned char hash[SHA256_DIGEST_LENGTH];
#else
	unsigned char hash[MD5_DIGEST_LENGTH];
#endif

	if (!load_public_key(&pkey))
		return CRYPTO_CHECK_NO_PUBLICKEY;
	if (!decode_header_info(&hdr, pkey, &hash_length))
		return CRYPTO_CHECK_NO_HEADER;
	RSA_free(pkey);

	/* Decrypt image if needed */
	if (hdr.flags & FLAG_ENCRYPTED) {
		unsigned char cin[AES_BLOCK_SIZE];
		unsigned char cout[AES_BLOCK_SIZE];
		unsigned long s;
		AES_KEY key;

		if (fb_seek_set(0) < 0) {
			error("Can not decrypt encrypted image when -t option is used.");
			exit(BAD_CRYPT);
		}

		if ((hash_length % AES_BLOCK_SIZE) != 0) {
			error("image size not miscable with cryptography");
			exit(BAD_CRYPT);
		}
		AES_set_decrypt_key(hdr.aeskey, AESKEYSIZE * 8, &key);
		/* Convert the body of the file */
		for (s = 0; s < hash_length; s += AES_BLOCK_SIZE) {
			fb_peek(cin, AES_BLOCK_SIZE);
			AES_decrypt(cin, cout, &key);
			fb_write(cout, AES_BLOCK_SIZE);
		}
	}

	/* Remove padding */
	if (hdr.padsize) {
		hash_length -= hdr.padsize;
#ifdef CONFIG_USER_NETFLASH_CRYPTO_V2
		fb_meta_add(hdr.padsize);
#else
		fb_trim(hdr.padsize);
#endif
	}

	if (crypto_hash_init) {
		if (crypto_hash_total > hash_length) {
			error("hashed too much, try without -t");
			exit(BAD_MD5_SIG);
		}
		fb_seek_set(crypto_hash_total);
	} else {
#ifdef CONFIG_USER_NETFLASH_CRYPTO_V2
		SHA256_Init(&sha_ctx);
#else
		MD5_Init(&md5_ctx);
#endif
		fb_seek_set(0);
	}

	while ((data = fb_read_block(&fblength)) != NULL) {
		length = fblength;
		if (length > (hash_length - crypto_hash_total)) {
			length = hash_length - crypto_hash_total;
		}
#ifdef CONFIG_USER_NETFLASH_CRYPTO_V2
		SHA256_Update(&sha_ctx, data, length);
#else
		MD5_Update(&md5_ctx, data, length);
#endif
		if (length != fblength)
			break;
		crypto_hash_total += length;
	}

#ifdef CONFIG_USER_NETFLASH_CRYPTO_V2
	SHA256_Final(hash, &sha_ctx);
	if (memcmp(hdr.hash, hash, SHA256_DIGEST_LENGTH) != 0) {
		error("bad SHA256 signature");
		exit(BAD_MD5_SIG);
	}
#else
	MD5_Final(hash, &md5_ctx);
	if (memcmp(hdr.md5, hash, MD5_DIGEST_LENGTH) != 0) {
		error("bad MD5 signature");
		exit(BAD_MD5_SIG);
	}
#endif

	notice("signed image approved");
	return CRYPTO_CHECK_OK;
}