| ... | ... | @@ -130,21 +130,55 @@ fn AES(comptime keysize: usize) type { |
| 130 | 130 | return struct { |
| 131 | 131 | const Self = @This(); |
| 132 | 132 | |
| 133 | pub const Encrypt = AESEncrypt(keysize); |
| 134 | pub const Decrypt = AESDecrypt(keysize); |
| 135 | |
| 133 | 136 | const nn = (keysize / 8) + 28; |
| 134 | | enc: [nn]u32, |
| 135 | | dec: [nn]u32, |
| 137 | enc: Encrypt, |
| 138 | dec: Decrypt, |
| 136 | 139 | |
| 137 | 140 | pub fn init(key: [keysize / 8]u8) Self { |
| 138 | 141 | var ctx: Self = undefined; |
| 139 | | expandKey(&key, ctx.enc[0..], ctx.dec[0..]); |
| 142 | ctx.enc = Encrypt.init(key); |
| 143 | ctx.dec = ctx.enc.toDecrypt(); |
| 140 | 144 | return ctx; |
| 141 | 145 | } |
| 142 | 146 | |
| 143 | 147 | pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void { |
| 144 | | encryptBlock(ctx.enc[0..], dst, src); |
| 148 | ctx.enc.encrypt(dst, src); |
| 145 | 149 | } |
| 146 | 150 | pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void { |
| 147 | | decryptBlock(ctx.dec[0..], dst, src); |
| 151 | ctx.dec.decrypt(dst, src); |
| 152 | } |
| 153 | pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void { |
| 154 | ctx.enc.ctr(dst, src, iv); |
| 155 | } |
| 156 | }; |
| 157 | } |
| 158 | |
| 159 | fn AESEncrypt(comptime keysize: usize) type { |
| 160 | return struct { |
| 161 | const Self = @This(); |
| 162 | |
| 163 | const Decrypt = AESDecrypt(keysize); |
| 164 | |
| 165 | const nn = (keysize / 8) + 28; |
| 166 | enc: [nn]u32, |
| 167 | |
| 168 | pub fn init(key: [keysize / 8]u8) Self { |
| 169 | var ctx: Self = undefined; |
| 170 | expandKeyEncrypt(&key, ctx.enc[0..]); |
| 171 | return ctx; |
| 172 | } |
| 173 | |
| 174 | pub fn toDecrypt(ctx: Self) Decrypt { |
| 175 | var dec: Decrypt = undefined; |
| 176 | expandKeyDecrypt(ctx.enc[0..], dec.dec[0..]); |
| 177 | return dec; |
| 178 | } |
| 179 | |
| 180 | pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void { |
| 181 | encryptBlock(ctx.enc[0..], dst, src); |
| 148 | 182 | } |
| 149 | 183 | pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void { |
| 150 | 184 | std.debug.assert(dst.len >= src.len); |
| ... | ... | @@ -163,6 +197,27 @@ fn AES(comptime keysize: usize) type { |
| 163 | 197 | }; |
| 164 | 198 | } |
| 165 | 199 | |
| 200 | fn AESDecrypt(comptime keysize: usize) type { |
| 201 | return struct { |
| 202 | const Self = @This(); |
| 203 | |
| 204 | const nn = (keysize / 8) + 28; |
| 205 | dec: [nn]u32, |
| 206 | |
| 207 | pub fn init(key: [keysize / 8]u8) Self { |
| 208 | var ctx: Self = undefined; |
| 209 | var enc: [nn]u32 = undefined; |
| 210 | expandKeyEncrypt(key[0..], enc[0..]); |
| 211 | expandKeyDecrypt(enc[0..], ctx.dec[0..]); |
| 212 | return ctx; |
| 213 | } |
| 214 | |
| 215 | pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void { |
| 216 | decryptBlock(ctx.dec[0..], dst, src); |
| 217 | } |
| 218 | }; |
| 219 | } |
| 220 | |
| 166 | 221 | test "ctr" { |
| 167 | 222 | // NIST SP 800-38A pp 55-58 |
| 168 | 223 | { |
| ... | ... | @@ -247,7 +302,7 @@ test "decrypt" { |
| 247 | 302 | } |
| 248 | 303 | |
| 249 | 304 | // Key expansion algorithm. See FIPS-197, Figure 11. |
| 250 | | fn expandKey(key: []const u8, enc: []u32, dec: []u32) void { |
| 305 | fn expandKeyEncrypt(key: []const u8, enc: []u32) void { |
| 251 | 306 | var i: usize = 0; |
| 252 | 307 | var nk = key.len / 4; |
| 253 | 308 | while (i < nk) : (i += 1) { |
| ... | ... | @@ -262,9 +317,11 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void { |
| 262 | 317 | } |
| 263 | 318 | enc[i] = enc[i - nk] ^ t; |
| 264 | 319 | } |
| 320 | } |
| 265 | 321 | |
| 322 | fn expandKeyDecrypt(enc: []const u32, dec: []u32) void { |
| 323 | var i: usize = 0; |
| 266 | 324 | var n = enc.len; |
| 267 | | i = 0; |
| 268 | 325 | while (i < n) : (i += 4) { |
| 269 | 326 | var ei = n - i - 4; |
| 270 | 327 | var j: usize = 0; |
| ... | ... | @@ -308,7 +365,8 @@ test "expand key" { |
| 308 | 365 | }; |
| 309 | 366 | var enc: [exp_enc.len]u32 = undefined; |
| 310 | 367 | var dec: [exp_dec.len]u32 = undefined; |
| 311 | | expandKey(key[0..], enc[0..], dec[0..]); |
| 368 | expandKeyEncrypt(key[0..], enc[0..]); |
| 369 | expandKeyDecrypt(enc[0..], dec[0..]); |
| 312 | 370 | testing.expectEqualSlices(u32, exp_enc[0..], enc[0..]); |
| 313 | 371 | testing.expectEqualSlices(u32, exp_dec[0..], dec[0..]); |
| 314 | 372 | } |