PKCS#7 padding

This commit is contained in:
Armin Friedl 2025-02-09 17:41:40 +01:00
parent 9388cf69ba
commit 522883fa1f
2 changed files with 113 additions and 0 deletions

View file

@ -5,6 +5,7 @@ const xor = @import("xor.zig");
const xor_crack = @import("xor_crack.zig");
const aes = @import("aes.zig");
const aes_crack = @import("aes_crack.zig");
const padding = @import("padding.zig");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -46,6 +47,10 @@ pub fn main() !void {
if (std.mem.eql(u8, args[1], "s1c8")) {
try s1c8(allocator, stdout);
}
if (std.mem.eql(u8, args[1], "s1c9")) {
try s1c9(allocator, stdout);
}
}
fn s1c1(allocator: std.mem.Allocator, stdout: anytype) !void {
@ -252,3 +257,12 @@ fn s1c8(allocator: std.mem.Allocator, stdout: anytype) !void {
lineno += 1;
}
}
fn s1c9(allocator: std.mem.Allocator, stdout: anytype) !void {
const input = "YELLOW SUBMARINE";
const result = try padding.pkcs7(allocator, input, 20);
defer allocator.free(result);
try stdout.print("{s}", .{result});
}

99
src/padding.zig Normal file
View file

@ -0,0 +1,99 @@
const std = @import("std");
/// Pad a buffer with PKCS#7. Caller must free result.
pub fn pkcs7(allocator: std.mem.Allocator, buf: []const u8, block_size: u8) ![]u8 {
if (block_size == 0) return error.InvalidBlockSize;
const diff: u8 = switch (buf.len % block_size) {
0 => 0,
else => |v| @intCast(block_size - v),
};
const out = try allocator.alloc(u8, buf.len + diff);
std.mem.copyForwards(u8, out, buf);
for (buf.len..out.len) |i| out[i] = diff;
return out;
}
test "pad_oversized_blocksize_with_remainder" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 20);
defer allocator.free(res);
// 16 byte input, 20 byte blocksize -> padded to 1*20=20 byte with 4 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE\x04\x04\x04\x04", res);
}
test "pad_triple_oversized_blocksize_with_remainder" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 52);
defer allocator.free(res);
// 16 byte input, 52 (3*16+4) byte blocksize -> padded to 1*52=52
// byte with 36 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24", res);
}
test "pad_exact_blocksize_no_remainder" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 16);
defer allocator.free(res);
// 16 byte input, 16 byte blocksize -> padded to 1*16=16 byte with
// 0 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE", res);
}
test "pad_double_blocksize" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 32);
defer allocator.free(res);
// 16 byte input, 32 byte blocksize -> padded to 1*32=32 byte with
// 16 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10", res);
}
test "pad_half_blocksize" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 8);
defer allocator.free(res);
// 16 byte input, 8 byte blocksize -> padded to 2*8=16 byte with 0 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE", res);
}
test "pad_undersized_blocksize_remainder" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 6);
defer allocator.free(res);
// 16 byte input, 6 byte blocksize -> padded to 3*6=18 byte with 2 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE\x02\x02", res);
}
test "pad_max_blocksize" {
const allocator = std.testing.allocator;
const input = "YELLOW SUBMARINE";
const res = try pkcs7(allocator, input, 255);
defer allocator.free(res);
// 16 byte input, 255 byte blocksize -> padded to 1*255=255 byte with 239 byte padding
try std.testing.expectEqualStrings("YELLOW SUBMARINE\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef\xef", res);
}