Skip to documentation
SLOP

tiny.quic.crypto.retry

Reference tiny.quic crypto retry

Defined in crypto.

API (8)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callscryptoretry
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallscrypto.retryverifytest sourcelib.quic.src.crypto.test.test_RFC_9000_sectio...8 Retry maximum plus onetest sourcelib.quic.src.crypto.test.test_RFC_9001_Append...4 Retry integrity tagprivate sourcelib.quic.src.properties.protectioncompareRetryTagprivate sourcelib.quic.src.crypto.retryauthenticatecrypto.retrytag
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.quic.src.crypto.test.test_RFC_9000_sectio...8 Retry maximum plus onetest sourcelib.quic.src.crypto.test.test_RFC_9001_Append...4 Retry integrity tagprivate sourcelib.quic.src.properties.crypto.Totalitypropertyprivate sourcelib.quic.src.properties.protectioncompareRetryVerifycrypto.retrytagcrypto.retryverify
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/quic/src/crypto/retry.zig

zig
const std = @import("std");const quic = @import("../root.zig");const Aes128 = std.crypto.core.aes.Aes128;const Ghash = std.crypto.onetimeauth.Ghash;pub const tag_bytes: usize = Ghash.mac_length;pub const connection_id_bytes_max: usize = 20;pub const pseudo_bytes_max: usize = quic.crypto.packet.packet_bytes_max - tag_bytes;/// The 16-byte AES-128 key RFC 9001 section 5.8 fixes for QUIC version 1 Retry integrity tags. A/// caller checking a Retry integrity tag against another implementation needs the key that/// implementation used. Every endpoint uses it, so the tag shows the sender saw the original/// destination connection ID. It carries no proof of the sender's identity.pub const v1_key = [_]u8{    0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a,    0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e,};/// The 12-byte nonce RFC 9001 section 5.8 fixes for QUIC version 1 Retry integrity tags. It pairs/// with the key for the same check. The tag computation uses it with the fixed key over the/// pseudo-packet.pub const v1_nonce = [_]u8{    0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63,    0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,};pub const TagError = error{    ConnectionIdTooLong,    PacketTooLarge,};fn authenticate(prefix: []const u8, retry_pseudo: []const u8) [tag_bytes]u8 {    const aad_len = prefix.len + retry_pseudo.len;    const cipher = Aes128.initEnc(v1_key);    var hash_key: [Ghash.key_length]u8 = undefined;    cipher.encrypt(&hash_key, &@splat(0));    const block_count = @divCeil(aad_len, Ghash.block_length) + 1;    var mac = Ghash.initForBlockCount(&hash_key, block_count);    mac.update(prefix);    mac.update(retry_pseudo);    mac.pad();    var lengths: [Ghash.block_length]u8 = @splat(0);    std.mem.writeInt(u64, lengths[0..8], @as(u64, aad_len) * 8, .big);    mac.update(&lengths);    var result: [tag_bytes]u8 = undefined;    mac.final(&result);    var counter: [Aes128.block.block_length]u8 = @splat(0);    counter[0..v1_nonce.len].* = v1_nonce;    std.mem.writeInt(u32, counter[v1_nonce.len..][0..4], 1, .big);    var encrypted_counter: [Aes128.block.block_length]u8 = undefined;    cipher.encrypt(&encrypted_counter, &counter);    for (0..tag_bytes) |index| result[index] ^= encrypted_counter[index];    return result;}pub fn tag(odcid: []const u8, retry_pseudo: []const u8) TagError![tag_bytes]u8 {    if (odcid.len > connection_id_bytes_max) return error.ConnectionIdTooLong;    if (retry_pseudo.len > pseudo_bytes_max) return error.PacketTooLarge;    var prefix: [1 + connection_id_bytes_max]u8 = undefined;    prefix[0] = @intCast(odcid.len);    @memcpy(prefix[1..][0..odcid.len], odcid);    return authenticate(prefix[0 .. 1 + odcid.len], retry_pseudo);}pub fn verify(odcid: []const u8, retry_packet: []const u8) bool {    if (odcid.len > connection_id_bytes_max) return false;    if (retry_packet.len <= tag_bytes) return false;    if (retry_packet.len > quic.crypto.packet.packet_bytes_max) return false;    const tag_offset = retry_packet.len - tag_bytes;    const expected = tag(odcid, retry_packet[0..tag_offset]) catch return false;    const actual: [tag_bytes]u8 = retry_packet[tag_offset..][0..tag_bytes].*;    return std.crypto.timing_safe.eql([tag_bytes]u8, expected, actual);}

Source: lib/quic/src/crypto/root.zig:20

zig
pub const retry = @import("retry.zig");

Audit

Definitions9
Public names9
Members2
Version26.7.0
Revisiondaab053ee433