Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 15 Oct 2016 17:35:58 +0200
From: Hanno Böck <hanno@...eck.de>
To: oss-security@...ts.openwall.com
Cc: cve-assign@...re.org
Subject: Update on MatrixSSL miscalculation (incomplete fix for
 CVE-2016-6887)

https://blog.fuzzing-project.org/54-Update-on-MatrixSSL-miscalculation-incomplete-fix-for-CVE-2016-6887.html

CVE-assigners: I think this could get a CVE as an incomplete fix for
CVE-2016-6887

----------

I recently [1] reported how I found various bugs in the bignum
implementation of MatrixSSL, some of them leading to remotely
exploitable vulnerabilities.

One of the bugs was that the modular exponentiation function -
pstm_exptmod() - produced wrong results for some inputs . This wasn't
really fixed, but only worked around by restricting the allowed size of
the modulus. Not surprisingly it is still possible to find inputs that
cause miscalculations (code). I reported this to MatrixSSL on August
1st.

Recently MatrixSSL released another update (3.8.6) fixing several
vulnerabilities reported by Craig Young from Tripwire [2]. However the
pstm_exptmod() bug is still there.

It is unclear how exploitable such bugs are, but given that it's used
in the context of cryptographic functions handling secret key material
this is clearly a reason for concern.

MatrixSSL has long advertised itself as a safer alternative to OpenSSL,
because it didn't suffer from the same kind of high severity bugs. I
think it has been sufficiently shown that this was due to the fact that
nobody was looking. But what's more worrying is that bugs they knew
about for several months now don't get fixed properly.

[1]
https://blog.fuzzing-project.org/51-Fun-with-Bignums-Crashing-MatrixSSL-and-more.html
[2]
http://www.tripwire.com/state-of-security/security-data-protection/cyber-security/flawed-matrixssl-code-highlights-need-for-better-iot-update-practices/


-- 
Hanno Böck
https://hboeck.de/

mail/jabber: hanno@...eck.de
GPG: FE73757FA60E4E21B937579FA5880072BBB51E42

/* MatrixSSL miscalculation bug
 * demonstrating incomplete fix for Use CVE-2016-6887
 *
 * by Hanno Böck, license: CC0 / public domain
 */

#include <stdio.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <crypto/cryptoApi.h>

unsigned char a1[] = {
  0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff,
  0xff, 0xff, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xb7, 0xcc, 0x03, 0x00, 0x00
};

unsigned int a1_len = 197;

unsigned char b1[] = {
  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00
};

unsigned int b1_len = 50;

unsigned char m1[] = {
  0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xb9, 0x6c, 0x00,
  0x00, 0x00, 0x00, 0xff
};

unsigned int m1_len = 64;

/* test bn functions from openssl/libcrypto */
char *bntest(unsigned char *a_raw, int a_len, unsigned char *b_raw, int b_len,
	     unsigned char *m_raw, int m_len)
{
	BN_CTX *bctx = BN_CTX_new();
	BIGNUM *a = BN_new();
	BIGNUM *b = BN_new();
	BIGNUM *m = BN_new();
	BIGNUM *res1 = BN_new();
	char *result;

	BN_bin2bn(a_raw, a_len, a);
	BN_bin2bn(b_raw, b_len, b);
	BN_bin2bn(m_raw, m_len, m);

	BN_mod_exp(res1, a, b, m, bctx);
	result = BN_bn2hex(res1);
	printf("openssl:\n%s\n", result);

	BN_free(a);
	BN_free(b);
	BN_free(m);
	BN_free(res1);
	BN_CTX_free(bctx);

	return result;
}

char *matrixtest(unsigned char *a_raw, int a_len, unsigned char *b_raw,
		 int b_len, unsigned char *m_raw, int m_len)
{
	unsigned char *rr = malloc(4096);
	char *buf, *buf_ptr;
	int i, s;
	pstm_int a, b, m, r;

	if (pstm_init_for_read_unsigned_bin(NULL, &a, a_len) < 0) {
		printf("pstm_init_for_read_unsigned_bin a error\n");
		return 0;
	}
	if (pstm_read_unsigned_bin(&a, a_raw, a_len) != 0) {
		printf("pstm_read_unsigned_bin a error\n");
		return 0;
	}
	if (pstm_init_for_read_unsigned_bin(NULL, &b, b_len) < 0) {
		printf("pstm_init_for_read_unsigned_bin b error\n");
		return 0;
	}
	if (pstm_read_unsigned_bin(&b, b_raw, b_len) != 0) {
		printf("pstm_read_unsigned_bin b error\n");
		return 0;
	}
	if (pstm_init_for_read_unsigned_bin(NULL, &m, m_len) < 0) {
		printf("pstm_init_for_read_unsigned_bin c error\n");
		return 0;
	}
	if (pstm_read_unsigned_bin(&m, m_raw, m_len) != 0) {
		printf("pstm_read_unsigned_bin c error\n");
		return 0;
	}

	if (pstm_init(NULL, &r) != 0) {
		printf("pstm_init r error\n");
		return 0;
	}

	if (pstm_exptmod(NULL, &a, &b, &m, &r) != 0) {
		printf("pstm_exptmod error\n");
		return 0;
	}

	if (pstm_to_unsigned_bin(0, &r, rr) < 0) {
		printf("pstm_to_unsigned_bin error\n");
		return 0;
	}
	s = pstm_unsigned_bin_size(&r);
	buf = buf_ptr = malloc(s * 2 + 1);
	for (i = 0; i < s; i++) {
		buf_ptr += sprintf(buf_ptr, "%02X", rr[i]);
	}

	printf("matrixssl:\n%s\n", buf);
	return buf;
}

int main(int argc, char *argv[])
{
	char *r1, *r2;

	r1 = matrixtest(a1, a1_len, b1, b1_len, m1, m1_len);

	r2 = bntest(a1, a1_len, b1, b1_len, m1, m1_len);

	if (strcmp(r1, r2) != 0)
		printf("Results differ!\n");

	return 0;
}


[ CONTENT OF TYPE application/pgp-signature SKIPPED ]

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ