Commit 96a4cf8c authored by Andy Polyakov's avatar Andy Polyakov
Browse files

crypto/modes: even more strict aliasing fixes [and fix bug in cbc128.c from

previous cbc128.c commit].
parent da01515c
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -137,11 +137,13 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
				out += 16;
			}
		}
		else {
		else  if (16%sizeof(size_t) == 0) { /* always true */
			while (len>=16) {
				size_t *out_t=(size_t *)out, *iv_t=(size_t *)iv;

				(*block)(in, out, key);
				for(n=0; n<16; n+=sizeof(size_t))
					*(size_t *)(out+n) ^= *(size_t *)(iv+n);
				for(n=0; n<16/sizeof(size_t); n++)
					out_t[n] ^= iv_t[n];
				iv = in;
				len -= 16;
				in  += 16;
@@ -166,18 +168,19 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
			}
		}
		else if (16%sizeof(size_t) == 0) { /* always true */
			while (len>=16) {
				size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
				const size_t *in_t=(const size_t *)in;
			while (len>=16) {
				(*block)((const unsigned char *)in_t, tmp.c, key);

				(*block)(in, tmp.c, key);
				for(n=0; n<16/sizeof(size_t); n++) {
					c = in_t[n];
					out_t[n] = tmp.t[n] ^ ivec_t[n];
					ivec_t[n] = c;
				}
				len -= 16;
				in_t  += 16/sizeof(size_t);
				out_t += 16/sizeof(size_t);
				in  += 16;
				out += 16;
			}
		}
	}
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
		ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
	}
	else
		*(u32*)(&ctx->nonce.c[8]) = 0;
		ctx->nonce.u[1] = 0;

	ctx->nonce.c[12] = (u8)(mlen>>24);
	ctx->nonce.c[13] = (u8)(mlen>>16);
+8 −20
Original line number Diff line number Diff line
@@ -108,12 +108,8 @@ size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
	(*cbc)(in,out-16,residue,key,ivec,1);
	memcpy(out,tmp.c,residue);
#else
	{
	size_t n;
	for (n=0; n<16; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = 0;
	memset(tmp.c,0,sizeof(tmp));
	memcpy(tmp.c,in,residue);
	}
	memcpy(out,out-16,residue);
	(*cbc)(tmp.c,out-16,16,key,ivec,1);
#endif
@@ -144,12 +140,8 @@ size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
#if defined(CBC_HANDLES_TRUNCATED_IO)
	(*cbc)(in,out-16+residue,residue,key,ivec,1);
#else
	{
	size_t n;
	for (n=0; n<16; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = 0;
	memset(tmp.c,0,sizeof(tmp));
	memcpy(tmp.c,in,residue);
	}
	(*cbc)(tmp.c,out-16+residue,16,key,ivec,1);
#endif
	return len+residue;
@@ -177,8 +169,7 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,

	(*block)(in,tmp.c+16,key);

	for (n=0; n<16; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
	memcpy(tmp.c,tmp.c+16,16);
	memcpy(tmp.c,in+16,residue);
	(*block)(tmp.c,tmp.c,key);

@@ -220,8 +211,7 @@ size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *o

	(*block)(in+residue,tmp.c+16,key);

	for (n=0; n<16; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
	memcpy(tmp.c,tmp.c+16,16);
	memcpy(tmp.c,in,residue);
	(*block)(tmp.c,tmp.c,key);

@@ -240,7 +230,7 @@ size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *o
size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
			size_t len, const void *key,
			unsigned char ivec[16], cbc128_f cbc)
{	size_t residue, n;
{	size_t residue;
	union { size_t align; unsigned char c[32]; } tmp;

	assert (in && out && key && ivec);
@@ -257,8 +247,7 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
		out += len;
	}

	for (n=16; n<32; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = 0;
	memset(tmp.c,0,sizeof(tmp));
	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
	(*cbc)(in,tmp.c,16,key,tmp.c+16,0);

@@ -275,7 +264,7 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
			size_t len, const void *key,
			unsigned char ivec[16], cbc128_f cbc)
{	size_t residue, n;
{	size_t residue;
	union { size_t align; unsigned char c[32]; } tmp;

	assert (in && out && key && ivec);
@@ -297,8 +286,7 @@ size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
		out += len;
	}

	for (n=16; n<32; n+=sizeof(size_t))
		*(size_t *)(tmp.c+n) = 0;
	memset(tmp.c,0,sizeof(tmp));
	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
	(*cbc)(in+residue,tmp.c,16,key,tmp.c+16,0);

+31 −19
Original line number Diff line number Diff line
@@ -962,8 +962,9 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
		    size_t j=GHASH_CHUNK;

		    while (j) {
			size_t *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
@@ -983,15 +984,17 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
		    size_t j=i;

		    while (len>=16) {
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
				PUTU32(ctx->Yi.c+12,ctr);
			else
				ctx->Yi.d[3] = ctr;
			for (i=0; i<16; i+=sizeof(size_t))
				*(size_t *)(out+i) =
				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
			for (i=0; i<16/sizeof(size_t); ++i)
				out_t[i] = in_t[i] ^ ctx->EKi.t[i];
			out += 16;
			in  += 16;
			len -= 16;
@@ -1000,16 +1003,18 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
		}
#else
		while (len>=16) {
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
				PUTU32(ctx->Yi.c+12,ctr);
			else
				ctx->Yi.d[3] = ctr;
			for (i=0; i<16; i+=sizeof(size_t))
				*(size_t *)(ctx->Xi.c+i) ^=
				*(size_t *)(out+i) =
				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
			for (i=0; i<16/sizeof(size_t); ++i)
				ctx->Xi.t[i] ^=
				out_t[i] = in_t[i]^ctx->EKi.t[i];
			GCM_MUL(ctx,Xi);
			out += 16;
			in  += 16;
@@ -1113,15 +1118,17 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,

		    GHASH(ctx,in,GHASH_CHUNK);
		    while (j) {
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
				PUTU32(ctx->Yi.c+12,ctr);
			else
				ctx->Yi.d[3] = ctr;
			for (i=0; i<16; i+=sizeof(size_t))
				*(size_t *)(out+i) =
				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
			for (i=0; i<16/sizeof(size_t); ++i)
				out_t[i] = in_t[i]^ctx->EKi.t[i];
			out += 16;
			in  += 16;
			j   -= 16;
@@ -1131,15 +1138,17 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
		if ((i = (len&(size_t)-16))) {
		    GHASH(ctx,in,i);
		    while (len>=16) {
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
				PUTU32(ctx->Yi.c+12,ctr);
			else
				ctx->Yi.d[3] = ctr;
			for (i=0; i<16; i+=sizeof(size_t))
				*(size_t *)(out+i) =
				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
			for (i=0; i<16/sizeof(size_t); ++i)
				out_t[i] = in_t[i]^ctx->EKi.t[i];
			out += 16;
			in  += 16;
			len -= 16;
@@ -1147,16 +1156,19 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
		}
#else
		while (len>=16) {
		    	size_t *out_t=(size_t *)out;
		    	const size_t *in_t=(const size_t *)in;

			(*block)(ctx->Yi.c,ctx->EKi.c,key);
			++ctr;
			if (is_endian.little)
				PUTU32(ctx->Yi.c+12,ctr);
			else
				ctx->Yi.d[3] = ctr;
			for (i=0; i<16; i+=sizeof(size_t)) {
				size_t c = *(size_t *)(in+i);
				*(size_t *)(out+i) = c^*(size_t *)(ctx->EKi.c+i);
				*(size_t *)(ctx->Xi.c+i) ^= c;
			for (i=0; i<16/sizeof(size_t); ++i) {
				size_t c = in[i];
				out[i] = c^ctx->EKi.t[i];
				ctx->Xi.t[i] ^= c;
			}
			GCM_MUL(ctx,Xi);
			out += 16;