Skip to content

GCM allows empty nonce (IV) leading to authentication subkey recovery #16

Description

@lifeng8425

The GCM implementation in zig-bearssl (via the underlying BearSSL library) allows an empty nonce (IV) to be used. When the IV length is zero, the authentication subkey H can be recovered by an attacker, allowing them to forge arbitrary messages with valid authentication tags.

This behavior violates the NIST SP 800-38D standard, which explicitly prohibits zero-length IVs for GCM.

The following Zig code demonstrates the issue by encrypting empty plaintext with an empty IV and empty AAD. The resulting tag is directly equal to the authentication subkey H, confirming the vulnerability. (Note: empty plaintext and AAD are permitted by the GCM specification.)


const std = @import("std");
const bearssl = @import("bearssl");

pub fn main() !void {
var ctx: bearssl.br_gcm_context = undefined;
var tag: [16]u8 = undefined;
var h: [16]u8 = undefined;

// Use vtable and GHASH implementation exported by zig-bearssl
const bctx: *const bearssl.br_block_ctr_class = &bearssl.br_aes_ct64_ctr_vtable;
const gh = bearssl.br_ghash_ctmul64;

bearssl.br_gcm_init(&ctx, &bctx, gh);
std.mem.copy(u8, &h, &ctx.h);

bearssl.br_gcm_reset(&ctx, null, 0);      // empty IV (length 0)
bearssl.br_gcm_aad_inject(&ctx, null, 0);
bearssl.br_gcm_flip(&ctx);
bearssl.br_gcm_run(&ctx, 1, null, 0);     // empty plaintext
bearssl.br_gcm_get_tag(&ctx, &tag);

const stdout = std.io.getStdOut().writer();
try stdout.print("H: ", .{});
for (h) |b| try stdout.print("{x:0>2}", .{b});
try stdout.print("\nTag: ", .{});
for (tag) |b| try stdout.print("{x:0>2}", .{b});
try stdout.print("\n", .{});

if (std.mem.eql(u8, &h, &tag)) {
    try stdout.print("Match! Empty IV results in Tag = H\n", .{});
} else {
    try stdout.print("Not match\n", .{});
}

}


output:
H: 49439c63679dc163daf03a63571a1063
Tag: 49439c63679dc163daf03a63571a1063
Match! Empty IV results in Tag = H

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions