Pular para o conteúdo
ecdsa.com
C

Mbed TLS (TF-PSA-Crypto)

O Mbed TLS 4.x, a pilha TLS para sistemas embarcados cuja criptografia agora é a PSA Crypto API: assinaturas ECDSA r‖s brutas, ECDSA determinístico como algoritmo separado e políticas de chave que fixam o algoritmo de cada chave.
Licença
Apache-2.0 OR GPL-2.0-or-later
Versão verificada
4.1.1 ·
Código-fonte
github.com/Mbed-TLS/mbedtls
Documentação
mbed-tls.readthedocs.io/

Visão geral da compatibilidade

ECDSAPós-quântica

Curvas ECDSA
P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1
EdDSA
none
Formatos de chave pública
spki-dersec1-uncompressed

O Mbed TLS 4 transferiu a criptografia para o TF-PSA-Crypto e a PSA Crypto API (psa_sign_message, psa_verify_message, psa_generate_key), a mesma API usada pelo Trusted Firmware da Arm. Os fatos desta página foram verificados no pacote do Alpine 3.24.2, Mbed TLS 4.1.1 (o projeto original já estava na 4.2.0); os recursos dependem da configuração do build, como em toda biblioteca embarcada.

O que difere do código derivado do OpenSSL é a codificação da assinatura: a PSA retorna a forma r‖s bruta, 64 bytes na P-256, e não DER. Assinaturas destinadas a X.509, CMS ou a um verificador OpenSSL precisam ser empacotadas em DER, e as assinaturas DER vindas desses sistemas precisam ser desempacotadas antes de psa_verify_message, que, do contrário, retorna PSA_ERROR_INVALID_SIGNATURE — o mesmo status de uma assinatura forjada ou de um blob de 3 bytes. Converta com o conversor DER ⇄ bruto.

Cada chave carrega uma política com um único algoritmo permitido, então a escolha entre PSA_ALG_ECDSA (nonce aleatório) e PSA_ALG_DETERMINISTIC_ECDSA (RFC 6979 — o vetor de teste da RFC foi reproduzido) é feita na criação da chave, como mostra o exemplo. O s não é normalizado, e a verificação aceita high-S. psa_sign_hash assina um digest pré-calculado.

Este build assinou e verificou com P-256, P-384, P-521, secp256k1 e as curvas Brainpool r1; a P-224 não estava disponível, e a geração de chaves Ed25519 foi recusada (PSA_ERROR_NOT_SUPPORTED). O suporte pós-quântico se limita à verificação de LMS, um esquema de assinatura baseada em hash (MBEDTLS_LMS_C); não há tipo de chave ML-KEM nem ML-DSA, e o driver experimental de ML-DSA do mldsa-native (TF_PSA_CRYPTO_PQCP_MLDSA_ENABLED) está comentado na configuração deste build. As chaves públicas são exportadas pela PSA como pontos SEC1 na forma não comprimida e pela camada pk como SPKI DER.

Os fatos e as verificações por trás deles

Nada abaixo foi copiado da documentação. A verificação content/libraries/verify/mbedtls/run.sh executou Mbed TLS (TF-PSA-Crypto) 4.1.1 na imagem de contêiner alpine:3.24.2 em 20 de outubro de 2026; a página precisa corresponder ao que a verificação imprimiu, e cada fato lista essas linhas.

  • Codificação da assinatura ECDSA

    raw

    psa_sign_message retornou 64 bytes de r‖s brutos na P-256.

    Registrado pela verificação
    fact ecdsa-signature-encoding = raw
    evidence ecdsa-signature-encoding: psa_sign_message returned 64 bytes
  • Nonce do ECDSA

    rfc6979-opt-in

    PSA_ALG_ECDSA usa um nonce aleatório; PSA_ALG_DETERMINISTIC_ECDSA reproduziu o apêndice A.2.5 da RFC 6979.

    Registrado pela verificação
    fact ecdsa-nonce = rfc6979-opt-in
    evidence ecdsa-nonce: PSA_ALG_ECDSA repeats: no; PSA_ALG_DETERMINISTIC_ECDSA reproduces the RFC 6979 A.2.5 r: yes (status 0)
  • Low-S ao assinar

    either

    O s não é normalizado: apareceram valores high-S em 64 assinaturas.

    Registrado pela verificação
    fact ecdsa-low-s-sign = either
  • High-S ao verificar

    accepts-high-s

    Uma assinatura com s substituído por n − s passou na verificação.

    Registrado pela verificação
    fact ecdsa-low-s-verify = accepts-high-s
  • Entrada do hash na chamada de assinatura

    hashes-message-or-digest

    psa_sign_message calcula o hash; psa_sign_hash assina um digest, e essa assinatura foi verificada com psa_verify_message.

    Registrado pela verificação
    fact ecdsa-prehash = hashes-message-or-digest
  • Assinatura ECDSA malformada

    returns-false

    Uma assinatura DER, um blob de 3 bytes e uma assinatura válida sobre outros dados retornaram, todos, PSA_ERROR_INVALID_SIGNATURE (-149).

    Registrado pela verificação
    fact ecdsa-malformed-signature = returns-false
    evidence ecdsa-malformed-signature: psa_verify_message status: DER -149, 3 bytes -149, wrong message -149 (PSA_ERROR_INVALID_SIGNATURE = -149)
  • Curvas ECDSA

    P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1

    Assinatura e verificação funcionaram com P-256, P-384, P-521, secp256k1 e brainpoolP256r1/P384r1/P512r1; a geração de chaves P-224 falhou neste build.

    Registrado pela verificação
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
  • EdDSA

    none

    A geração de chaves Ed25519 retornou PSA_ERROR_NOT_SUPPORTED (-134).

    Registrado pela verificação
    fact eddsa = none
    evidence eddsa: psa_generate_key for an Ed25519 key: status -134
  • Algoritmos pós-quânticos

    LMS

    MBEDTLS_LMS_C está habilitado (verificação de assinaturas LMS); nenhum tipo de chave PSA ML-KEM ou ML-DSA é definido, e o driver experimental mldsa-native não é compilado.

    Registrado pela verificação
    fact pqc = LMS
    evidence pqc: MBEDTLS_LMS_C is enabled (LMS hash-based signature verification, <mbedtls/lms.h>)
    evidence pqc: no ML-DSA or ML-KEM PSA key type is defined in these headers
    evidence pqc: psa/crypto_config.h of this build: //#define TF_PSA_CRYPTO_PQCP_MLDSA_ENABLED;//#define TF_PSA_CRYPTO_PQCP_MLDSA_87_ENABLED (commented out = the experimental mldsa-native driver is not built)
  • Formatos de chave pública

    spki-dersec1-uncompressed

    psa_export_public_key retorna o ponto SEC1 de 65 bytes na forma não comprimida; SPKI DER é gravado e lido pela camada pk.

    Registrado pela verificação
    fact public-key-formats = spki-der, sec1-uncompressed
    evidence public-key-formats: psa_export_public_key returns 65 bytes starting 0x04 (an uncompressed SEC1 point)

Uso

Crie uma chave P-256 cuja política permita ECDSA determinístico, assine uma mensagem e verifique a assinatura bruta de 64 bytes.
#include <psa/crypto.h>
#include <stdio.h>

int main(void) {
    if (psa_crypto_init() != PSA_SUCCESS) return 1;
    /* The algorithm is part of the key policy: here deterministic ECDSA (RFC 6979) with SHA-256. */
    psa_algorithm_t alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
    psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
    psa_set_key_bits(&attr, 256);
    psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
    psa_set_key_algorithm(&attr, alg);
    psa_key_id_t key;
    if (psa_generate_key(&attr, &key) != PSA_SUCCESS) return 1;

    const uint8_t msg[] = "order #1042 approved";
    uint8_t sig[PSA_SIGNATURE_MAX_SIZE];
    size_t sig_len;
    psa_sign_message(key, alg, msg, sizeof msg - 1, sig, sizeof sig, &sig_len);

    /* PSA signatures are raw r||s (64 bytes on P-256): wrap them in DER for X.509 or OpenSSL peers. */
    psa_status_t status = psa_verify_message(key, alg, msg, sizeof msg - 1, sig, sig_len);
    printf("signature bytes: %zu, verified: %d\n", sig_len, status == PSA_SUCCESS);
    psa_destroy_key(key);
    return 0;
}

O executor de trechos de código roda cada exemplo literalmente na imagem de contêiner alpine:3.24.2, e a execução falha se a saída não corresponder.

Configuração
apk add --no-cache -q build-base mbedtls-dev=4.1.1-r0 >/dev/null
Comando
cc -o usage usage.c -lmbedcrypto -ltfpsacrypto && ./usage
A saída deve corresponder a (expressão regular)
signature bytes: 64, verified: 1

Bibliotecas