--- a/sys/crypto/rijndael/rijndael-alg-fst.c 2026-10-19 02:42:10.856656601 +0000 +++ b/sys/crypto/rijndael/rijndael-alg-fst.c 2026-10-19 02:42:30.064412310 +0000 @@ -735,6 +735,11 @@ int i = 0; u32 temp; + if (keyBits != 128 && keyBits != 192 && keyBits != 256) { + /* KASSERT alone is a no-op on production (non-INVARIANTS) + * kernels; falling through would return 0 (Nr=0). */ + return -1; + } KASSERT(keyBits == 128 || keyBits == 192 || keyBits == 256, ("Invalid key size (%d).", keyBits)); rk[0] = GETU32(cipherKey ); @@ -823,6 +828,8 @@ int Nr, i, j; u32 temp; + if (keyBits != 128 && keyBits != 192 && keyBits != 256) + return -1; /* expand the cipher key: */ Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); /* invert the order of the round keys: */ @@ -865,6 +872,12 @@ int r; #endif /* ?FULL_UNROLL */ + if (Nr != 10 && Nr != 12 && Nr != 14) { + /* rejects the Nr=0 stored by a broken key setup (and any + * other impossible round count) before the round loop */ + return; + } + /* * map byte array block to cipher state * and add initial round key: @@ -1046,6 +1059,9 @@ int r; #endif /* ?FULL_UNROLL */ + if (Nr != 10 && Nr != 12 && Nr != 14) + return; + /* * map byte array block to cipher state * and add initial round key: --- a/sys/crypto/rijndael/rijndael-api.c 2026-10-19 02:42:10.856656601 +0000 +++ b/sys/crypto/rijndael/rijndael-api.c 2026-10-19 02:42:30.076412157 +0000 @@ -38,6 +38,17 @@ rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits) { + /* + * rijndaelKeySetupEnc/Dec only KASSERT the key size, which is + * compiled out on production kernels and would store Nr=0 with + * a partially-written schedule. Reject bad sizes here instead. + */ + if (bits != 128 && bits != 192 && bits != 256) { + ctx->Nr = 0; + bzero(ctx->ek, sizeof(ctx->ek)); + bzero(ctx->dk, sizeof(ctx->dk)); + return; + } ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits); rijndaelKeySetupDec(ctx->dk, key, bits); }