123 lines
3.1 KiB
Text
123 lines
3.1 KiB
Text
/* ZUPT — AES-256 Single Block Encrypt via AES-NI (Jasmin)
|
|
* Copyright (c) 2026 Cristian Cezar Moisés
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*
|
|
* CT-REQUIRED: designed without intended secret-dependent branches or memory
|
|
* access. Compiled and microarchitectural timing is not proven here.
|
|
*
|
|
* FIX v2.0.0: replaced `stack u128[15] rk` with 15 individual
|
|
* `stack u128` variables. The array form uses byte-offset indexing
|
|
* in jasminc (rk.[1] → [rsp+1] instead of [rsp+16]), producing
|
|
* incorrect round key loads. Individual variables avoid the issue.
|
|
*/
|
|
|
|
inline fn key_expand_even(reg u128 t0, reg u128 assist) -> reg u128 {
|
|
reg u128 tmp;
|
|
assist = #VPSHUFD(assist, 0xFF);
|
|
tmp = #VPSLLDQ(t0, 4);
|
|
t0 ^= tmp;
|
|
tmp = #VPSLLDQ(t0, 4);
|
|
t0 ^= tmp;
|
|
tmp = #VPSLLDQ(t0, 4);
|
|
t0 ^= tmp;
|
|
t0 ^= assist;
|
|
return t0;
|
|
}
|
|
|
|
inline fn key_expand_odd(reg u128 t0, reg u128 t1) -> reg u128 {
|
|
reg u128 tmp assist;
|
|
assist = #VAESKEYGENASSIST(t0, 0);
|
|
assist = #VPSHUFD(assist, 0xAA);
|
|
tmp = #VPSLLDQ(t1, 4);
|
|
t1 ^= tmp;
|
|
tmp = #VPSLLDQ(t1, 4);
|
|
t1 ^= tmp;
|
|
tmp = #VPSLLDQ(t1, 4);
|
|
t1 ^= tmp;
|
|
t1 ^= assist;
|
|
return t1;
|
|
}
|
|
|
|
export fn zupt_aes256_blk(
|
|
reg u64 out_ptr,
|
|
reg ptr u128[1] in_blk,
|
|
reg ptr u128[2] key,
|
|
reg ptr u128[1] ctr_blk)
|
|
{
|
|
stack u128 rk0 rk1 rk2 rk3 rk4 rk5 rk6 rk7;
|
|
stack u128 rk8 rk9 rk10 rk11 rk12 rk13 rk14;
|
|
reg u128 t0 t1 assist b data;
|
|
|
|
t0 = key.[0];
|
|
t1 = key.[1];
|
|
rk0 = t0;
|
|
rk1 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x01);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk2 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk3 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x02);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk4 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk5 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x04);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk6 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk7 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x08);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk8 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk9 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x10);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk10 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk11 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x20);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk12 = t0;
|
|
t1 = key_expand_odd(t0, t1);
|
|
rk13 = t1;
|
|
|
|
assist = #VAESKEYGENASSIST(t1, 0x40);
|
|
t0 = key_expand_even(t0, assist);
|
|
rk14 = t0;
|
|
|
|
b = ctr_blk.[0];
|
|
b ^= rk0;
|
|
b = #VAESENC(b, rk1);
|
|
b = #VAESENC(b, rk2);
|
|
b = #VAESENC(b, rk3);
|
|
b = #VAESENC(b, rk4);
|
|
b = #VAESENC(b, rk5);
|
|
b = #VAESENC(b, rk6);
|
|
b = #VAESENC(b, rk7);
|
|
b = #VAESENC(b, rk8);
|
|
b = #VAESENC(b, rk9);
|
|
b = #VAESENC(b, rk10);
|
|
b = #VAESENC(b, rk11);
|
|
b = #VAESENC(b, rk12);
|
|
b = #VAESENC(b, rk13);
|
|
b = #VAESENCLAST(b, rk14);
|
|
|
|
data = in_blk.[0];
|
|
b ^= data;
|
|
[out_ptr + 0] = b;
|
|
|
|
reg u128 wipe;
|
|
wipe = rk0; wipe ^= wipe;
|
|
rk0 = wipe; rk1 = wipe; rk2 = wipe; rk3 = wipe;
|
|
rk4 = wipe; rk5 = wipe; rk6 = wipe; rk7 = wipe;
|
|
rk8 = wipe; rk9 = wipe; rk10 = wipe; rk11 = wipe;
|
|
rk12 = wipe; rk13 = wipe; rk14 = wipe;
|
|
}
|