
Biblioteca Zig de Módulo de Segurança de Hardware para tokens PIV, CAC e YubiKey via PC/SC. Suporta certificados, gerenciamento de PIN, assinatura e descriptografia.
Uma biblioteca Hardware Security Module (HSM) para Zig que fornece acesso PC/SC a tokens PIV, CAC e YubiKey.
| Aspecto | Informação |
|---|---|
| Estabilidade da API | Desenvolvimento |
| Versão Zig | 0.16.0 |
| Plataformas | Linux, macOS, Windows |
| Licença | MIT |
Suporte PIV (NIST SP 800-73-4)
Suporte CAC (Common Access Card)
Suporte YubiKey
Segurança
anyerror)Operações Paralelas (via thread_pool)
-Denable_tp=true); desative com -Denable_tp=falselibpcsclite-dev (Debian/Ubuntu) ou pcsc-lite-devel (Fedora)# Debian/Ubuntu
sudo apt-get install libpcsclite-dev pcscd
# Fedora/RHEL
sudo dnf install pcsc-lite-devel pcsc-lite
# Iniciar o daemon PC/SC
sudo systemctl start pcscd
sudo systemctl enable pcscd
# Compilar e executar testes unitários
make
# Ou usando zig diretamente
zig build test
# Executar testes de integração do simulador
zig build test -Dintegration_sim=true
# Compilar exemplos (requer biblioteca PC/SC instalada)
zig build examples -Dlink_pcsc=true
| Opção | Padrão | Descrição | Impacto na Segurança |
|---|---|---|---|
integration_sim | false | Executar testes de integração do simulador | Nenhum |
hsm_hil | false | Executar testes com hardware real (requer token real) | Nenhum |
link_pcsc | false | Vincular biblioteca PC/SC para exemplos | Nenhum |
include_simulator | Debug: trueRelease: false | Incluir simulador PIV com chaves de teste | CWE-321: Chaves de teste em produção |
allow_pcsc_env_override | false | RISCO DE SEGURANÇA: Permitir variável de ambiente HSM_PCSC_LIB_PATH | CWE-427: Carregamento de biblioteca não confiável |
fips | false | Roteamento de criptografia de segurança através do provedor FIPS-140-3 vinculado (sobrecarga zero quando desativado) | Nenhum quando desativado |
openssl_path | (não definido) | Prefixo de instalação do OpenSSL para instalações não padrão (ex.: /usr/local/ssl) | Nenhum |
Com -Dfips=true, toda primitiva criptográfica relevante para segurança
é roteada através de um provedor FIPS OpenSSL 3.x vinculado e validado,
via a costura crypto_backend, e o simulador ganha operações de token
PIV pós-quânticas (assinatura ML-DSA-65, encapsulamento/desencapsulamento
ML-KEM-768) que estão disponíveis apenas no modo FIPS. A flag está
desativada por padrão, com sobrecarga zero; a dependência fips é
resolvida apenas sob -Dfips=true.
# Compilação padrão — backend std.crypto, sem vínculo OpenSSL
zig build test
# Compilação FIPS — provedor FIPS OpenSSL (execute `make deps` a partir de fips primeiro)
OPENSSL_CONF=/usr/local/ssl/ssl/openssl.cnf \
zig build test -Dfips=true -Dopenssl_path=/usr/local/ssl
# Ambos os modos de uma vez
make test-dual
Consulte docs/FIPS.md para o design da costura, a
política de isenção de FIPS e as operações de token PQC.
Nota de Segurança: A opção allow_pcsc_env_override está desativada por padrão para evitar ataques de injeção de bibliotecas maliciosas (CWE-427). Ative-a apenas para desenvolvimento/teste:
# Compilação de produção (segura, variável de ambiente ignorada)
zig build
# Compilação de desenvolvimento (permite HSM_PCSC_LIB_PATH)
zig build -Dallow_pcsc_env_override=true
Quando ativada, as bibliotecas são validadas antes do carregamento:
const std = @import("std");
const hsm = @import("hsm");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Listar tokens disponíveis
const tokens = try hsm.listTokens(allocator, false);
defer {
for (tokens) |*t| t.deinit();
allocator.free(tokens);
}
if (tokens.len == 0) {
std.debug.print("Nenhum token encontrado\n", .{});
return;
}
// Abrir o primeiro token
var token = try hsm.openToken(allocator, tokens[0].id, .{});
defer token.close();
// Verificar PIN
try token.verifyPin("123456");
// Ler certificado
const cert = try token.getCertificate(.authentication);
defer allocator.free(cert);
std.debug.print("Certificado: {} bytes\n", .{cert.len});
// Assinar um digest
var digest: [32]u8 = undefined;
std.crypto.hash.sha2.Sha256.hash("Hello, PIV!", &digest, .{});
const signature = try token.sign(.authentication, .ecdsa_p256, &digest);
defer allocator.free(signature);
std.debug.print("Assinatura: {} bytes\n", .{signature.len});
}
| Tipo | Descrição |
|---|---|
TokenKind | Tipo de token: .piv, .cac, .yubikey, .unknown |
TokenInfo | Metadados de token descoberto |
Token | Handle de token aberto para operações |
Slot | Slot de chave: .authentication (9A), .signature (9C), .key_management (9D), .card_auth (9E) |
Algorithm | Algoritmo criptográfico: .ecdsa_p256, .ecdsa_p384, .rsa2048_pkcs1v15, etc. |
Capabilities | Flags de capacidade do token |
PcscScope | Escopo do contexto PC/SC: .user (padrão), .system |
| Função | Descrição |
|---|---|
listTokens(allocator, use_sim) | Listar tokens disponíveis |
openToken(allocator, id, opts) | Abrir um token por ID |
token.reconnect() | Reconectar ao token e redefinir estado de autenticação |
token.verifyPin(pin) | Verificar PIN |
token.changePin(old, new) | Alterar PIN |
token.unblockPin(puk, new_pin) | Desbloquear PIN com PUK |
token.getCertificate(slot) | Obter certificado codificado em DER |
token.sign(slot, alg, digest) | Assinar um digest |
token.decrypt(slot, alg, ciphertext) | Descriptografar dados |
token.capabilities() | Obter capacidades do token |
token.close() | Fechar conexão do token |
Todas as operações retornam erros de HsmError:
PcscUnavailable, ReaderGone, CardRemoved, TimeoutPinIncorrect, PinLocked, PinLengthInvalidNotSupported, SlotNotFound, AlgorithmNotSupportedInvalidTlv, CertificateNotFound, InvalidDigestLengthSecurityConditionNotSatisfied, AuthenticationFailed