Ejemplo n.º 1
0
/* get_string
 *
 * This gets a printable string from the memory buffer.
 * It searchs backwards for a non-printable character or a NULL terminator.
 *
 * inputs:
 *
 * str/len - the buffer to store the string in.
 *
 * ret:
 *
 * -1 - we couldn't find the string.
 * 0 - success
 */
int get_string(char *str, int len)
{
	int i, j;
	char c;

	for (i = 0; i < len; i++) {
		fb_peek(str + i, 1);
		if (fb_seek_dec(1) != 0)
			return -1;
		if (!str[i])
			break;
		if (!isprint(str[i]))
			return -1;
	}
	if (i == 0 || i >= len)
		return -1;

	/* We read string in reverse order, so reverse it again */
	for (j=0; j<i/2; j++) {
		c = str[j];
		str[j] = str[i-j-1];
		str[i-j-1] = c;
	}

	return 0;
}
Ejemplo n.º 2
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;
}