⬢ DragonFlyBSD Kernel Audit
DF-3568 / rijkat.c
← back to finding ↓ download raw
/*
 * rijkat.c - known-answer test for sys/crypto/rijndael/rijndael-api.c
 * (compiled as userland objects from the guest's /usr/src/sys tree).
 *
 * Vectors: FIPS-197 Appendix C (AES-128/192/256 single-block).
 * Also demonstrates Nr==0 silent-garbage behavior for invalid keyBits
 * (the non-INVARIANTS production-kernel path; userland KASSERT mirrors
 * INVARIANTS so invalid-bits calls are split into a separate binary).
 */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <crypto/rijndael/rijndael.h>

static int failcnt;

struct vec { int bits; const char *k, *p, *c; };

static struct vec vecs[] = {
{128, "000102030405060708090a0b0c0d0e0f",
      "00112233445566778899aabbccddeeff",
      "69c4e0d86a7b0430d8cdb78070b4c55a"},
{192, "000102030405060708090a0b0c0d0e0f1011121314151617",
      "00112233445566778899aabbccddeeff",
      "dda97ca4864cdfe06eaf70a0ec0d7191"},
{256, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
      "00112233445566778899aabbccddeeff",
      "8ea2b7ca516745bfeafc49904b496089"},
};

static int
hex2bin(const char *hex, unsigned char *out, int maxlen)
{
	int n = 0;
	while (hex[0] && hex[1] && n < maxlen) {
		unsigned v;
		sscanf(hex, "%2x", &v);
		out[n++] = v;
		hex += 2;
	}
	return n;
}

static void
bin2hex(const unsigned char *b, int n, char *out)
{
	int i;
	for (i = 0; i < n; i++)
		sprintf(out + 2*i, "%02x", b[i]);
	out[2*n] = 0;
}

int
main(void)
{
	unsigned char key[32], pt[16], ct[16], rt[16], expct[16];
	char hex[64];
	int i;

	for (i = 0; i < (int)(sizeof(vecs)/sizeof(vecs[0])); i++) {
		rijndael_ctx ctx;

		hex2bin(vecs[i].k, key, 32);
		hex2bin(vecs[i].p, pt, 16);
		hex2bin(vecs[i].c, expct, 16);

		rijndael_set_key(&ctx, key, vecs[i].bits);
		rijndael_encrypt(&ctx, pt, ct);
		bin2hex(ct, 16, hex);
		if (strcmp(hex, vecs[i].c) == 0)
			printf("PASS fips197-%d enc %s\n", vecs[i].bits, hex);
		else {
			printf("FAIL fips197-%d enc got %s want %s\n",
			    vecs[i].bits, hex, vecs[i].c);
			failcnt++;
		}
		rijndael_decrypt(&ctx, ct, rt);
		if (memcmp(rt, pt, 16) == 0)
			printf("PASS fips197-%d dec roundtrip\n", vecs[i].bits);
		else {
			bin2hex(rt, 16, hex);
			printf("FAIL fips197-%d dec got %s\n", vecs[i].bits, hex);
			failcnt++;
		}
		printf("  Nr=%d (expect %d)\n", ctx.Nr,
		    vecs[i].bits == 128 ? 10 : vecs[i].bits == 192 ? 12 : 14);
	}

	printf("%s: %d failures\n", failcnt ? "RESULT-FAIL" : "RESULT-PASS", failcnt);
	return failcnt ? 1 : 0;
}