Expand description
C ABI for gmcrypto-core (v0.4 W4).
Exposes SM2 (sign/verify, encrypt/decrypt, and — since v1.2 — the
GM/T 0003.3 key exchange with key confirmation) / SM3 / SM4
(ECB/CBC/CTR/GCM/CCM/XTS) / HMAC-SM3 / PBKDF2-HMAC-SM3 plus SM2 key
import/export and — since v1.4 — X.509-with-SM2 leaf certificate
parse + signature verify (NO trust decisions) to C / C++ / Python /
Go / Zig / Ruby callers via opaque handles and a cbindgen-generated
header at include/gmcrypto.h.
§Failure-mode invariant
Every entry point returning c_int uses the convention:
0= success.- Non-zero = failure (single-
Failed-equivalent per the workspace failure-mode invariant; no enumerated error codes).
C callers MUST treat all non-zero returns as opaque failure. Per
Q4.8 in docs/v0.4-scope.md, distinguishing failure modes would
introduce a padding-oracle / wrong-password-oracle attack surface.
§Output buffer convention
Entry points emitting variable-length output (signatures,
ciphertexts, PKCS#8 blobs) follow the
(out_ptr, out_capacity, out_actual_len) shape per Q4.13:
out_ptr: caller-allocated buffer.out_capacity: buffer length in bytes.out_actual_len: pointer to asize_twhere the entry point writes the actual output length (or the required capacity if the buffer was too small).
On too-small buffer: return non-zero, write the required length
to *out_actual_len, do not modify out_ptr.
§Handle ownership
Opaque handles are heap-allocated Box<T>s returned as
*mut T_t. Callers MUST pair each _new with exactly one
_free to avoid leaks. Double-free or use-after-free is
undefined behaviour (per Box::from_raw’s contract). Calling
_free(NULL) is a no-op (mirrors C’s free() semantics).
§Constant-time
The FFI shim itself does not introduce new secret-touching paths.
Every cryptographic operation runs in gmcrypto-core’s already-
dudect-gated code. The null-pointer check at each entry point
is constant-time (single integer compare); the return-on-null
early-exit has a different timing signature than a successful
call, but the attacker who could measure this is local-host and
has far more invasive options.
§Panic discipline
Every entry point wraps its body in std::panic::catch_unwind.
Rust panics unwinding into C are undefined behaviour; on panic
we convert to a non-zero return. Per the failure-mode invariant,
the C caller cannot distinguish panic from other failure modes.
Structs§
- gmcrypto_
hmac_ sm3_ t - Opaque handle for a streaming HMAC-SM3 keyed MAC.
- gmcrypto_
sm2_ kx_ initiator_ t - Opaque handle for an SM2 key-exchange INITIATOR (party A; GM/T
0003.3, v1.2). Born already awaiting the responder’s reply —
gmcrypto_sm2_kx_initiator_newsamples the ephemeral internally and writesR_Aimmediately, so no pre-ephemeral state exists in C. Pair with exactly onegmcrypto_sm2_kx_initiator_confirm(which consumes + frees) or onegmcrypto_sm2_kx_initiator_free. - gmcrypto_
sm2_ kx_ responder_ t - Opaque handle for an SM2 key-exchange RESPONDER (party B; GM/T
0003.3, v1.2). Lifecycle:
gmcrypto_sm2_kx_responder_new→gmcrypto_sm2_kx_responder_respond(takesR_A, emitsR_B+S_B) →gmcrypto_sm2_kx_responder_finish(takesS_A, releasesK, consumes + frees). Pair with exactly one_finishor onegmcrypto_sm2_kx_responder_free. - gmcrypto_
sm2_ privkey_ t - Opaque handle for an SM2 private key.
- gmcrypto_
sm2_ pubkey_ t - Opaque handle for an SM2 public key.
- gmcrypto_
sm3_ t - Opaque handle for a streaming SM3 hasher.
- gmcrypto_
sm4_ cbc_ decryptor_ t - Opaque handle for a streaming SM4-CBC decryptor (v0.5 W1). Same
buffer-back-by-one padding-oracle defense as the v0.3 W5 Rust
streaming surface: the most recent decrypted block is held back
from emission until
gmcrypto_sm4_cbc_decryptor_finalizeconfirms it is the last block and validates the PKCS#7 padding. - gmcrypto_
sm4_ cbc_ encryptor_ t - Opaque handle for a streaming SM4-CBC encryptor (v0.5 W1).
Construct with
gmcrypto_sm4_cbc_encryptor_new, feed plaintext viagmcrypto_sm4_cbc_encryptor_update, emit the trailing PKCS#7- padded block(s) viagmcrypto_sm4_cbc_encryptor_finalize. - gmcrypto_
sm4_ gcm_ decryptor_ t - Opaque handle for a streaming (incremental-input, output-BUFFERED)
SM4-GCM decryptor (v0.10 W2). Commit-on-verify:
gmcrypto_sm4_gcm_decryptor_updatebuffers ciphertext and emits nothing;gmcrypto_sm4_gcm_decryptor_finalize_verifyreleases the full plaintext only after a constant-time tag check. Memory isO(message). Construct withgmcrypto_sm4_gcm_decryptor_new. - gmcrypto_
sm4_ gcm_ encryptor_ t - Opaque handle for a streaming (incremental-input) SM4-GCM encryptor
(v0.10 W1). Output-streaming: each
gmcrypto_sm4_gcm_encryptor_updateemits the ciphertext for its chunk;gmcrypto_sm4_gcm_encryptor_finalizeemits the 16-byte tag. Construct withgmcrypto_sm4_gcm_encryptor_new; pair with exactly one finalize (which frees the handle) or onegmcrypto_sm4_gcm_encryptor_free. - gmcrypto_
sm4_ t - Opaque handle for an SM4 cipher (key-scheduled).
- gmcrypto_
tlcp_ record_ keys_ cbc_ t - Opaque per-direction SM4-CBC record key carrier (
ZeroizeOnDrop). Build withgmcrypto_tlcp_record_keys_cbc_new; free + wipe withgmcrypto_tlcp_record_keys_cbc_free. Immutable — protect/deprotect borrow it. - gmcrypto_
tlcp_ record_ keys_ gcm_ t - Opaque per-direction SM4-GCM record key carrier (
ZeroizeOnDrop). - gmcrypto_
x509_ certificate_ t - Opaque X.509 certificate handle (v1.4). Immutable after construction —
every accessor takes
const *; free withgmcrypto_x509_certificate_free. - gmcrypto_
x509_ time_ t - A certificate validity timestamp — plain calendar fields, mirroring the
Rust
X509Timeexactly (Zulu-only at parse). This library has no clock: comparing these to “now” (the actual validity decision) is the caller’s call.
Constants§
- GMCRYPTO_
ERR - Generic failure return code. All non-zero returns are equivalent per the failure-mode invariant; this constant exists only as a convenience for C callers that want a named symbol for the not-success case.
- GMCRYPTO_
OK - Success return code.
- GMCRYPTO_
SM2_ KX_ CONFIRM_ SIZE - SM2 key-exchange confirmation-tag size in bytes (
S_A/S_Bare SM3 digests; v1.2). Ephemeral pointsR_A/R_BuseGMCRYPTO_SM2_SEC1_UNCOMPRESSED_SIZE(65). - GMCRYPTO_
SM2_ SCALAR_ SIZE - SM2 private-key scalar size in bytes (32 = 256 bits big-endian).
- GMCRYPTO_
SM2_ SEC1_ UNCOMPRESSED_ SIZE - SEC1 uncompressed-point size for SM2 public keys
(
04 || X || Y= 65 bytes). - GMCRYPTO_
SM3_ DIGEST_ SIZE - SM3 digest output size in bytes (32 = 256 bits).
- GMCRYPTO_
SM4_ BLOCK_ SIZE - SM4 block size in bytes (16 = 128 bits).
- GMCRYPTO_
SM4_ KEY_ SIZE - SM4 key size in bytes (16 = 128 bits).
- GMCRYPTO_
SM4_ XTS_ KEY_ SIZE - SM4-XTS key size in bytes (32 =
Key1 ‖ Key2, two 128-bit keys). - GMCRYPTO_
TLCP_ CBC_ KEY_ BLOCK_ LEN - SM4-CBC record key-block length (bytes) for
gmcrypto_tlcp_record_keys_cbc_new. - GMCRYPTO_
TLCP_ FINISHED_ VERIFY_ DATA_ LEN - TLCP Finished
verify_datalength (bytes). - GMCRYPTO_
TLCP_ GCM_ KEY_ BLOCK_ LEN - SM4-GCM record key-block length (bytes) for
gmcrypto_tlcp_record_keys_gcm_new. - GMCRYPTO_
TLCP_ MASTER_ SECRET_ LEN - TLCP master-secret length (bytes).
- GMCRYPTO_
TLCP_ RECORD_ VERSION_ MAJOR - TLCP record version major byte (
0x01).versionis a caller parameter on every protect/deprotect call; these constants are a convenience. - GMCRYPTO_
TLCP_ RECORD_ VERSION_ MINOR - TLCP record version minor byte (
0x01). - GMCRYPTO_
X509_ MAX_ CHAIN_ DEPTH - Maximum chain length
gmcrypto_x509_verify_chainaccepts.
Functions§
- gmcrypto_
hmac_ ⚠sm3 - Single-shot HMAC-SM3. Writes 32 bytes to
out_tag. - gmcrypto_
hmac_ ⚠sm3_ finalize - Consume the streaming HMAC-SM3 instance and write the 32-byte tag
to
out_tag. The handle is freed by this call. - gmcrypto_
hmac_ ⚠sm3_ free - Free a streaming HMAC-SM3 instance. NULL is a no-op.
- gmcrypto_
hmac_ ⚠sm3_ new - Construct a fresh streaming HMAC-SM3 instance keyed with
key. Returns NULL on invalid input. - gmcrypto_
hmac_ ⚠sm3_ update - Absorb
datainto the streaming HMAC-SM3 instance. - gmcrypto_
hmac_ ⚠sm3_ verify - Consume the streaming HMAC-SM3 instance and verify the candidate
tag in constant time. Returns
GMCRYPTO_OKon match;GMCRYPTO_ERRon mismatch. The handle is freed by this call. - gmcrypto_
pbkdf2_ ⚠hmac_ sm3 - Derive
out_lenbytes via PBKDF2-HMAC-SM3 over(pwd, salt, iterations). Writes into the caller-suppliedoutbuffer. - gmcrypto_
sm2_ ⚠decrypt - SM2 private-key decrypt of a GM/T 0009-2012 DER ciphertext.
- gmcrypto_
sm2_ ⚠decrypt_ c1c2c3_ legacy - SM2 private-key decrypt of a legacy raw byte-concat
C1 || C2 || C3ciphertext. Decrypt-only — there is no emit path for the legacy ordering, and there will not be one in any v0.5+ version (perCLAUDE.md“Don’t” entry). - gmcrypto_
sm2_ ⚠decrypt_ c1c3c2 - SM2 private-key decrypt of a modern raw byte-concat
C1 || C3 || C2ciphertext. Input length must be at least65 + 32 + 1 = 98bytes (C1 + C3 + at least one C2 byte). - gmcrypto_
sm2_ ⚠encrypt - SM2 public-key encrypt. Output is GM/T 0009-2012 DER. RNG from
getrandom::SysRng. - gmcrypto_
sm2_ ⚠encrypt_ c1c3c2 - SM2 public-key encrypt; output in the modern raw byte-concat
C1 || C3 || C2format.C1is the 65-byte SEC1-uncompressed point (0x04 || X || Y);C3is the 32-byte SM3 MAC;C2ismsg_lenbytes of XOR-ed ciphertext. Output length is exactly65 + 32 + msg_len. - gmcrypto_
sm2_ ⚠encrypt_ with_ rng _with_rngvariant ofgmcrypto_sm2_encrypt. Identical contract except RNG bytes come from the caller’srng_callbackrather thangetrandom::SysRng.- gmcrypto_
sm2_ ⚠kx_ initiator_ confirm - Receive the responder’s reply and finish the initiator side:
verify
S_B(constant-time), and on success write the agreed key (exactlyklenbytes, theklengiven at_new) tokey_outand the initiator’s confirmation tagS_A(GMCRYPTO_SM2_KX_CONFIRM_SIZE= 32 bytes) toout_s_a— sendS_Ato the responder.r_bis the responder’s ephemeral point (65 bytes);s_bits confirmation tag (32 bytes). - gmcrypto_
sm2_ ⚠kx_ initiator_ derive_ unconfirmed - Complete the SM2 key exchange on the INITIATOR side WITHOUT key confirmation
(the TLCP Finished message plays the S_A/S_B role). CONSUMES + FREES the
gmcrypto_sm2_kx_initiator_thandle on every path; takes only the peerR_B(65 bytes, SEC104 ‖ X ‖ Y) and writes the agreed key (theklengiven at_new) tokey_out. An invalidR_Bis the singleGMCRYPTO_ERR. The caller owns wipingkey_out. Do NOT_freeafterwards. - gmcrypto_
sm2_ ⚠kx_ initiator_ free - Free an UNCONSUMED initiator handle (abandonment path — e.g. the
responder never replied). Safe on NULL. Do NOT call after
_confirm(which already consumed + freed the handle). - gmcrypto_
sm2_ ⚠kx_ initiator_ new - Construct a key-exchange INITIATOR (party A) and write its
ephemeral point
R_A(SEC1 uncompressed04 ‖ X ‖ Y, exactlyGMCRYPTO_SM2_SEC1_UNCOMPRESSED_SIZE= 65 bytes) toout_r_a. The handle is created already awaiting the responder’s reply: sendout_r_ato the responder, then callgmcrypto_sm2_kx_initiator_confirmwith its(R_B, S_B). - gmcrypto_
sm2_ ⚠kx_ initiator_ new_ with_ rng _with_rngvariant ofgmcrypto_sm2_kx_initiator_new: identical contract except the ephemeral randomness comes from the caller’srng_callback(the v0.5gmcrypto_rng_callbackshape) rather thangetrandom::SysRng. A null or failing callback returns NULL — indistinguishable from every other failure by design.- gmcrypto_
sm2_ ⚠kx_ responder_ finish - Verify the initiator’s confirmation tag
S_A(32 bytes, constant-time) and on success write the agreed key (exactlyklenbytes, theklengiven at_new) tokey_out. - gmcrypto_
sm2_ ⚠kx_ responder_ free - Free an UNCONSUMED responder handle (abandonment path — e.g. the
initiator never confirmed, or a
_respondfailure spent the handle). Safe on NULL. Do NOT call after_finish(which already consumed + freed the handle). Any held key material is wiped. - gmcrypto_
sm2_ ⚠kx_ responder_ new - Construct a key-exchange RESPONDER (party B).
local_privkeyis B’s static key;peer_pubkeyis A’s static public key; ids andklenfollow thegmcrypto_sm2_kx_initiator_newconventions (and must match the initiator’s, or the confirmation tags will not verify). The handle then waits for the initiator’sR_A— callgmcrypto_sm2_kx_responder_respond. - gmcrypto_
sm2_ ⚠kx_ responder_ respond - Receive the initiator’s
R_A(65 bytes) and produce the responder’s reply: writesR_B(65 bytes) toout_r_band the responder’s confirmation tagS_B(32 bytes) toout_s_b— send both to the initiator, then callgmcrypto_sm2_kx_responder_finishwith itsS_A. Ephemeral randomness comes from the OS (getrandom::SysRng). - gmcrypto_
sm2_ ⚠kx_ responder_ respond_ unconfirmed - Complete the SM2 key exchange on the RESPONDER side WITHOUT key confirmation
(single call — no S_A to verify). CONSUMES + FREES the handle; takes the
initiator’s
R_A(65 bytes), writesR_B(65 bytes) toout_r_band the agreed key (klenbytes) tokey_out. Ephemeral randomness comes from the OS. The caller owns wipingkey_out. Do NOT_freeafterwards. - gmcrypto_
sm2_ ⚠kx_ responder_ respond_ unconfirmed_ with_ rng _with_rngvariant ofgmcrypto_sm2_kx_responder_respond_unconfirmed: the ephemeral randomness comes fromrng_callbackrather than the OS. A NULL callback returnsGMCRYPTO_ERRWITHOUT consuming the handle (free it yourself), matching the confirmed_with_rngflow.- gmcrypto_
sm2_ ⚠kx_ responder_ respond_ with_ rng _with_rngvariant ofgmcrypto_sm2_kx_responder_respond: identical contract except the ephemeral randomness comes from the caller’srng_callbackrather thangetrandom::SysRng.- gmcrypto_
sm2_ ⚠privkey_ free - Free an SM2 private key. NULL is a no-op. The inner scalar is
zeroized via
ZeroizeOnDropbefore the heap slot is freed. - gmcrypto_
sm2_ ⚠privkey_ from_ pkcs8 - Load an SM2 private key from a password-encrypted PKCS#8 PEM blob.
On success, writes the new handle to
*out_keyand returnsGMCRYPTO_OK. Caller MUST free viagmcrypto_sm2_privkey_free. - gmcrypto_
sm2_ ⚠privkey_ new - Construct an SM2 private key from a 32-byte big-endian scalar.
Returns NULL on out-of-range scalar (must be in
[1, n-2]). - gmcrypto_
sm2_ ⚠privkey_ to_ pkcs8 - Emit a password-encrypted PKCS#8 PEM blob containing the SM2 private key. PBES2 / PBKDF2-HMAC-SM3 / SM4-CBC per RFC 8018.
- gmcrypto_
sm2_ ⚠privkey_ to_ sec1_ be - Export the SM2 private key as a 32-byte big-endian scalar.
- gmcrypto_
sm2_ ⚠pubkey_ free - Free an SM2 public key. NULL is a no-op.
- gmcrypto_
sm2_ ⚠pubkey_ new - Construct an SM2 public key from a SEC1 uncompressed-point byte
string (
04 || X || Y, 65 bytes). Returns NULL on invalid input (off-curve, identity point, non-uncompressed prefix). - gmcrypto_
sm2_ ⚠pubkey_ to_ sec1_ uncompressed - Export the SM2 public key as a SEC1 uncompressed-point byte
string (
04 || X || Y, 65 bytes). - gmcrypto_
sm2_ ⚠sign - Sign
msgwith the SM2 private key using the suppliedsigner_id(orDEFAULT_SIGNER_ID="1234567812345678"ifsigner_id_len == 0). Output is DER-encodedSEQUENCE { r, s }. RNG is sourced fromgetrandom::SysRng. - gmcrypto_
sm2_ ⚠sign_ with_ rng _with_rngvariant ofgmcrypto_sm2_sign. Identical contract except RNG bytes come from the caller’srng_callbackrather thangetrandom::SysRng.- gmcrypto_
sm2_ ⚠verify - Verify a DER-encoded
(r, s)signature againstmsgusing the SM2 public key andsigner_id. ReturnsGMCRYPTO_OKon valid;GMCRYPTO_ERRon invalid or any error. - gmcrypto_
sm3_ ⚠finalize - Consume the streaming SM3 hasher and write the digest to
out_digest. The handle is freed by this call; do not callgmcrypto_sm3_freeon it afterwards. - gmcrypto_
sm3_ ⚠free - Free a streaming SM3 hasher. Passing NULL is a no-op.
- gmcrypto_
sm3_ ⚠hash - Single-shot SM3 hash. Writes 32 bytes to
out_digest. - gmcrypto_
sm3_ new - Construct a fresh streaming SM3 hasher. Returns an opaque handle;
must be freed via
gmcrypto_sm3_free. - gmcrypto_
sm3_ ⚠update - Absorb
datainto the streaming SM3 hasher. - gmcrypto_
sm4_ ⚠cbc_ decrypt - SM4-CBC single-shot decrypt. Single-
Failedreturn on any failure mode (length not multiple of 16, bad padding, key/IV mismatch) per the failure-mode invariant. - gmcrypto_
sm4_ ⚠cbc_ decryptor_ finalize - Strip PKCS#7 padding from the held-back final block and emit the
last plaintext bytes. Consumes the decryptor — the handle is
freed by this call; do NOT call
gmcrypto_sm4_cbc_decryptor_freeon it afterwards. - gmcrypto_
sm4_ ⚠cbc_ decryptor_ free - Free a streaming SM4-CBC decryptor. Passing NULL is a no-op. Do
NOT call after
gmcrypto_sm4_cbc_decryptor_finalize— that already consumed the handle. - gmcrypto_
sm4_ ⚠cbc_ decryptor_ new - Construct a streaming SM4-CBC decryptor.
keyis exactly 16 bytes;ivis exactly 16 bytes and must match the value used during encryption. Returns NULL on invalid pointer input. - gmcrypto_
sm4_ ⚠cbc_ decryptor_ update - Absorb ciphertext into the streaming SM4-CBC decryptor and emit
zero or more full plaintext blocks. The final-candidate block is
HELD BACK from emission until
_finalizevalidates the trailing padding (buffer-back-by-one padding-oracle defense). Same buffer- size contract as the encryptor’s_update: caller MUST allocateout_capacity >= ct_len + 16(strict upper bound on bytes emitted in one call). On insufficient capacity returnsGMCRYPTO_ERRand the decryptor state is left mid-stream; size the buffer up-front. - gmcrypto_
sm4_ ⚠cbc_ encrypt - SM4-CBC single-shot encrypt with PKCS#7 padding. IV must be
caller-supplied and unpredictable (per NIST SP 800-38A
Appendix C). Output length is always
((pt_len / 16) + 1) * 16. - gmcrypto_
sm4_ ⚠cbc_ encryptor_ finalize - Apply PKCS#7 padding to the buffered tail and emit the final
ciphertext block(s). Consumes the encryptor — the handle is
freed by this call; do NOT call
gmcrypto_sm4_cbc_encryptor_freeon it afterwards. - gmcrypto_
sm4_ ⚠cbc_ encryptor_ free - Free a streaming SM4-CBC encryptor. Passing NULL is a no-op. Do
NOT call after
gmcrypto_sm4_cbc_encryptor_finalize— that already consumed the handle. - gmcrypto_
sm4_ ⚠cbc_ encryptor_ new - Construct a streaming SM4-CBC encryptor.
keyis exactly 16 bytes;ivis exactly 16 bytes and MUST be caller-supplied unpredictable bytes (NIST SP 800-38A Appendix C). Returns NULL on invalid pointer input. - gmcrypto_
sm4_ ⚠cbc_ encryptor_ update - Absorb plaintext into the streaming SM4-CBC encryptor and emit
zero or more full ciphertext blocks. The caller-allocated
outbuffer MUST be at leastpt_len + 16bytes — that is the upper bound on bytes emitted by a single_updatecall (a buffered partial block from a prior call can produce one extra block when this call’s input fills it). On insufficient capacity, the call returnsGMCRYPTO_ERRand the encryptor state is left mid- stream (the ciphertext bytes that would have been emitted are lost). Callers should size the output buffer correctly up-front. - gmcrypto_
sm4_ ⚠ccm_ decrypt - SM4-CCM single-shot decrypt. Input
ctisct_lenbytes (ciphertext ‖ tag);tag_lenmust match the value used at encrypt time.pt_outreceivesct_len - tag_lenbytes.GMCRYPTO_ERRon any failure (single failure mode). - gmcrypto_
sm4_ ⚠ccm_ encrypt - SM4-CCM single-shot encrypt.
tag_lenmust be in{4, 6, 8, 10, 12, 14, 16};nonce_lenin[7, 13].outreceivespt_len + tag_lenbytes (ciphertext ‖ tag). Invalid parameters →GMCRYPTO_ERR. - gmcrypto_
sm4_ ⚠decrypt_ block - Decrypt one 16-byte block in place under the SM4 cipher.
- gmcrypto_
sm4_ ⚠encrypt_ block - Encrypt one 16-byte block in place under the SM4 cipher.
- gmcrypto_
sm4_ ⚠free - Free an SM4 cipher. NULL is a no-op.
- gmcrypto_
sm4_ ⚠gcm_ decrypt - SM4-GCM single-shot decrypt with a 16-byte tag.
pt_outreceivesct_lenbytes. ReturnsGMCRYPTO_OKonly if the tag verifies;GMCRYPTO_ERRon any failure (single failure mode). - gmcrypto_
sm4_ ⚠gcm_ decrypt_ with_ tag_ len - SM4-GCM decrypt with a truncated tag.
tagistag_lenbytes;tag_lenmust be in{4, 8, 12, 13, 14, 15, 16}.pt_outreceivesct_lenbytes.GMCRYPTO_ERRon any failure. - gmcrypto_
sm4_ ⚠gcm_ decryptor_ finalize_ verify - Verify
tag(tag_lenbytes; the length is validated against the NIST-permitted set{4, 8, 12, 13, 14, 15, 16}) and, on success, write the full decrypted plaintext (length == total ciphertext fed) to(out, out_capacity, out_actual_len). - gmcrypto_
sm4_ ⚠gcm_ decryptor_ free - Free a streaming SM4-GCM decryptor without verifying (abort path).
NULL is a no-op. Do NOT call after
gmcrypto_sm4_gcm_decryptor_finalize_verify. - gmcrypto_
sm4_ ⚠gcm_ decryptor_ new - Construct a streaming SM4-GCM decryptor. Same parameter contract as
gmcrypto_sm4_gcm_encryptor_new. Returns NULL on invalid input. - gmcrypto_
sm4_ ⚠gcm_ decryptor_ update - Buffer
ct_lenbytes of ciphertext and fold them into the running GHASH. Emits no plaintext (commit-on-verify) — there is no output parameter. ReturnsGMCRYPTO_ERRonly on null handle or invalid input pointer; a length-ceiling overflow is latched and surfaces asGMCRYPTO_ERRatgmcrypto_sm4_gcm_decryptor_finalize_verify. - gmcrypto_
sm4_ ⚠gcm_ encrypt - SM4-GCM single-shot encrypt.
ct_outreceivespt_lenbytes (via the capacity/actual-len convention);tag_outreceives exactly 16 bytes. ReturnsGMCRYPTO_OK/GMCRYPTO_ERR. - gmcrypto_
sm4_ ⚠gcm_ encrypt_ with_ tag_ len - SM4-GCM encrypt with a truncated tag.
tag_lenmust be in{4, 8, 12, 13, 14, 15, 16};tag_outreceivestag_lenbytes. Invalidtag_len→GMCRYPTO_ERR. - gmcrypto_
sm4_ ⚠gcm_ encryptor_ finalize - Finish and emit the full 16-byte tag. Consumes the encryptor —
the handle is freed by this call (even on error); do NOT call
gmcrypto_sm4_gcm_encryptor_freeon it afterwards.tag_outmust be valid for exactly 16 bytes. - gmcrypto_
sm4_ ⚠gcm_ encryptor_ finalize_ with_ tag_ len - Finish and emit a truncated tag of
tag_lenbytes (MSB_tper NIST SP 800-38D §5.2.1.2).tag_lenmust be in{4, 8, 12, 13, 14, 15, 16}(elseGMCRYPTO_ERR). Consumes the encryptor — the handle is freed by this call (even on error); do NOT callgmcrypto_sm4_gcm_encryptor_freeafterwards. - gmcrypto_
sm4_ ⚠gcm_ encryptor_ free - Free a streaming SM4-GCM encryptor without finalizing (abort path).
Passing NULL is a no-op. Do NOT call after any
_finalize*— those already consumed the handle. - gmcrypto_
sm4_ ⚠gcm_ encryptor_ new - Construct a streaming SM4-GCM encryptor.
keyis exactly 16 bytes;nonceisnonce_lenbytes (12 = canonical; other lengths invoke the extra GHASH J0-derivation per NIST SP 800-38D §8.2.2);aadis the full associated data (the message header, supplied up-front). Returns NULL on invalid pointer/length input. Nonce uniqueness is the caller’s responsibility — reusing(key, nonce)is catastrophic for GCM. - gmcrypto_
sm4_ ⚠gcm_ encryptor_ update - Encrypt
pt_lenbytes of plaintext, emitting the ciphertext for this chunk (length ==pt_len; GCM does not pad or buffer). Theoutbuffer MUST be at leastpt_lenbytes; on insufficient capacity returnsGMCRYPTO_ERR(and the required length is written to*out_actual_len), and the encryptor state is left mid-stream (the chunk’s ciphertext is lost — size the buffer correctly). ReturnsGMCRYPTO_ERRonce the cumulative plaintext would exceed the GCM ceiling (2^36 − 32bytes); the encryptor is poisoned and all later calls also returnGMCRYPTO_ERR. - gmcrypto_
sm4_ ⚠new - Construct an SM4 cipher from a 16-byte key. Returns NULL on null key.
- gmcrypto_
sm4_ ⚠xts_ decrypt - SM4-XTS single-shot decrypt (GB/T 17964-2021,
xts_standard=GB). Inverse ofgmcrypto_sm4_xts_encryptwith the same argument shape;outreceivesdata_lenbytes. ReturnsGMCRYPTO_OK/GMCRYPTO_ERR(same single failure mode). XTS is unauthenticated, so decrypt cannot detect tampering — it only fails on invalid parameters (length / weak key / buffer). - gmcrypto_
sm4_ ⚠xts_ decrypt_ sectors - SM4-XTS in-place multi-sector decrypt (GB/T 17964-2021,
xts_standard=GB). Inverse ofgmcrypto_sm4_xts_encrypt_sectorsunder the same(key, sector_size, start_sector); same in-place contract, single failure mode, andbuf-untouched-on-error guarantee. XTS is unauthenticated, so decrypt cannot detect tampering — it only fails on invalid parameters. - gmcrypto_
sm4_ ⚠xts_ encrypt - SM4-XTS single-shot encrypt (GB/T 17964-2021,
xts_standard=GB).keyis exactlyGMCRYPTO_SM4_XTS_KEY_SIZE(32) bytes (Key1 ‖ Key2);tweakis exactlyGMCRYPTO_SM4_BLOCK_SIZE(16) raw bytes (the data-unit/sector identifier — caller-unique per key).outreceivesdata_lenbytes (length-preserving) via the capacity/actual-len convention. ReturnsGMCRYPTO_OK/GMCRYPTO_ERR(single failure mode:data_lenoutside[16, 16 MiB],Key1 == Key2, null pointer, or buffer too small — in which case*out_actual_lenis set to the required length). Confidentiality only — SM4-XTS does not authenticate. - gmcrypto_
sm4_ ⚠xts_ encrypt_ sectors - SM4-XTS in-place multi-sector encrypt (GB/T 17964-2021,
xts_standard=GB).keyis exactlyGMCRYPTO_SM4_XTS_KEY_SIZE(32) bytes (Key1 ‖ Key2);bufis a contiguous run ofbuf_len / sector_sizeequal-size sectors transformed in place (buf_lenmust be a whole multiple ofsector_size). Sectoriis encrypted under tweak = little-endian-128(start_sector + i) — the data-unit / LBA convention; sector numbers must be unique within the XTS-key namespace (caller’s contract).start_sectoris auint64_t(LBA width), so the addressable range is[0, 2^64 − 1]; for the full u128 sector space use the Rustmode_xts::encrypt_sectorsAPI. ReturnsGMCRYPTO_OK/GMCRYPTO_ERR(single failure mode:sector_sizeoutside[16, 16 MiB]or not a multiple of 16,buf_lennot a whole multiple ofsector_size,Key1 == Key2, or null pointer).bufis untouched onGMCRYPTO_ERR.buf_len == 0is a vacuousGMCRYPTO_OK(but the key is still validated, so empty + weak key →GMCRYPTO_ERR). Confidentiality only — SM4-XTS does not authenticate. - gmcrypto_
tlcp_ ⚠deprotect_ cbc - Deprotect an SM4-CBC record (
explicit_IV(16) ‖ CBC_ct) — the Lucky13 constant-time operation lives in core; this shim adds NO logic. The recovered plaintext goes to the copy-out buffer ONLY on success; on ANY failure (bad pad, bad MAC, bad length — indistinguishable) it returns a singleGMCRYPTO_ERRand touches NO output pointer. There is deliberately no length-in parameter (the post-strip length is secret). - gmcrypto_
tlcp_ ⚠deprotect_ gcm - Deprotect an SM4-GCM record (
explicit_nonce(8) ‖ ct ‖ tag(16), commit-on-verify). Plaintext to the copy-out buffer ONLY if the tag verifies; otherwise a singleGMCRYPTO_ERR(short record / over-ceiling / bad tag are indistinguishable). No length-in parameter. - gmcrypto_
tlcp_ ⚠derive_ key_ block - Expand the key block:
PRF(master_secret, "key expansion", server_random ‖ client_random). Writes exactlyout_lenbytes (the caller carves per suite — CBC 128, GCM 40).out_len == 0is vacuously OK. The caller owns wipingout. - gmcrypto_
tlcp_ ⚠derive_ master_ secret - Derive the 48-byte TLCP master secret from a 48-byte
pre_masterand the two 32-byte randoms. Infallible in core — returnsGMCRYPTO_ERRonly on a NULL pointer. The caller owns wipingpre_masterandout. - gmcrypto_
tlcp_ ⚠finished_ verify_ data - Compute the 12-byte Finished
verify_dataforrole(0= Client,1= Server).transcript_hashis the caller’s SM3 over the handshake messages (stateless). The caller owns wipingout. - gmcrypto_
tlcp_ ⚠protect_ cbc - Protect (MAC-then-encrypt) a plaintext record under SM4-CBC with HMAC-SM3,
a fresh OS-sampled explicit IV.
versionis 2 bytes; output to the(out, out_capacity, out_actual_len)copy-out buffer. SingleGMCRYPTO_ERR.(key, seq)uniqueness is the caller’s contract. - gmcrypto_
tlcp_ ⚠protect_ cbc_ with_ rng _with_rngvariant ofgmcrypto_tlcp_protect_cbc: the explicit IV comes fromrng_callback(REQUIRED for record-KAT reproduction) rather than the OS. A NULL callback returnsGMCRYPTO_ERR.- gmcrypto_
tlcp_ ⚠protect_ gcm - Protect a plaintext record under SM4-GCM (RFC 5288: seq-derived nonce, TLS
AAD). Output to the copy-out buffer; single
GMCRYPTO_ERR.(key, seq)uniqueness is the caller’s contract. - gmcrypto_
tlcp_ ⚠record_ keys_ cbc_ free - Free (and wipe) an SM4-CBC record key carrier. Safe on NULL.
- gmcrypto_
tlcp_ ⚠record_ keys_ cbc_ new - Carve the SM4-CBC record keys for
role(0= Client,1= Server) from a 128-byte (GMCRYPTO_TLCP_CBC_KEY_BLOCK_LEN) key block. Returns NULL on a bad role / NULL block. Free withgmcrypto_tlcp_record_keys_cbc_free. - gmcrypto_
tlcp_ ⚠record_ keys_ gcm_ free - Free (and wipe) an SM4-GCM record key carrier. Safe on NULL.
- gmcrypto_
tlcp_ ⚠record_ keys_ gcm_ new - Carve the SM4-GCM record keys for
rolefrom a 40-byte (GMCRYPTO_TLCP_GCM_KEY_BLOCK_LEN) key block. Returns NULL on a bad role / NULL block. Free withgmcrypto_tlcp_record_keys_gcm_free. - gmcrypto_
tlcp_ ⚠verify_ pair - Verify a TLCP [signature, encryption] certificate pair (each a leaf-first
chain) against the caller’s
anchors. Verdict to*out_verified. ReturnsGMCRYPTO_ERRonly on NULLout_verifiedor a malformed handle array. - gmcrypto_
version - Returns a NUL-terminated string with the
gmcrypto-ccrate version, tracking Cargo’sCARGO_PKG_VERSIONat build time (e.g."1.0.0"). The returned pointer is to a static&'static CStrand must NOT be freed by the caller. - gmcrypto_
x509_ ⚠certificate_ basic_ constraints - Read the
basicConstraintsextension. Writes1/0to*out_present(absent/malformed →0), thecAflag to*out_is_ca, and thepathLenConstraintto*out_path_lenguarded by*out_has_path_len(parsed, not enforced — informational). ReturnsGMCRYPTO_ERRonly on NULL. - gmcrypto_
x509_ ⚠certificate_ extensions_ raw - The
ExtensionsSEQUENCE TLV if present — shape-checked at parse but NEVER interpreted (criticalflags included); a caller building trust logic on top inherits RFC 5280 §4.2’s reject-unrecognized-critical obligation.*out_actual_len == 0means the optional extensions block is ABSENT (a present block is never empty), withGMCRYPTO_OK. Copy-out convention otherwise asgmcrypto_x509_certificate_tbs_raw. - gmcrypto_
x509_ ⚠certificate_ free - Free a certificate handle. NULL is a no-op.
- gmcrypto_
x509_ ⚠certificate_ from_ der - Parse a DER X.509-with-SM2 v3 leaf certificate (GM/T 0015 profile:
sm2-sign-with-sm3signature algorithm, SM2 SPKI). Returns NULL on ANY failure (null/empty input, malformed DER, wrong profile) — indistinguishable by design. Parsing makes NO trust decisions (no chain / time / extension / revocation logic — seegmcrypto-core’sx509module docs). - gmcrypto_
x509_ ⚠certificate_ is_ self_ issued - Write
1to*out_is_self_issuedif the certificate’s subject and issuerNames are byte-identical (the RFC 5280 self-ISSUED notion), else0; returnsGMCRYPTO_OKfor a successful evaluation,GMCRYPTO_ERRon null/bad arguments (“not self-issued” is NOT a failure). NOT “self-signed”: usegmcrypto_x509_certificate_verify_signatureagainst the cert’s own subject key for a self-signature check. - gmcrypto_
x509_ ⚠certificate_ issuer_ raw - The issuer
Nameas its full raw DER TLV — no interpretation; match issuers by byte equality. Copy-out convention asgmcrypto_x509_certificate_tbs_raw. - gmcrypto_
x509_ ⚠certificate_ key_ usage - Read the
keyUsageextension. Writes1/0to*out_present(absent OR malformed →0) and the raw bitmask to*out_bits(bit 0 =digitalSignature). ReturnsGMCRYPTO_ERRonly on NULL. - gmcrypto_
x509_ ⚠certificate_ not_ after - Write the certificate’s
notAfterinto*out_time. Exposure only — NO validity decision is made (seegmcrypto_x509_time_t). - gmcrypto_
x509_ ⚠certificate_ not_ before - Write the certificate’s
notBeforeinto*out_time. Exposure only — NO validity decision is made (seegmcrypto_x509_time_t). - gmcrypto_
x509_ ⚠certificate_ serial_ raw - The serial number as unsigned big-endian value bytes (the DER
disambiguating pad is stripped), 1..=20 bytes; negative serials were
rejected at parse. Copy-out convention as
gmcrypto_x509_certificate_tbs_raw. - gmcrypto_
x509_ ⚠certificate_ subject_ public_ key - The subject’s SM2 public key as a NEWLY allocated pubkey handle — the
caller owns it and frees it via
gmcrypto_sm2_pubkey_free. Composes withgmcrypto_sm2_verify/gmcrypto_sm2_encrypt/ the KX constructors — and withgmcrypto_x509_certificate_verify_signaturefor manual leaf-vs-CA chaining. NULL only on NULL input (the key was validated on-curve at parse). - gmcrypto_
x509_ ⚠certificate_ subject_ raw - The subject
Nameas its full raw DER TLV — no interpretation. Copy-out convention asgmcrypto_x509_certificate_tbs_raw. - gmcrypto_
x509_ ⚠certificate_ tbs_ raw - The exact
TBSCertificateTLV bytes as they appeared on the wire (the bytes the signature covers) — NOT re-encoded, NOT trust-validated. Copy-out convention: too-small buffer →GMCRYPTO_ERR+ required length in*out_actual_len. - gmcrypto_
x509_ ⚠certificate_ verify_ signature - Verify the certificate’s SM2-with-SM3 signature over the exact wire
tbsCertificatebytes against the issuer’s public key (issuer_pubkeyis a KEY handle, not an issuer certificate), using the GM / RFC 8998 default signer ID"1234567812345678". ReturnsGMCRYPTO_OKonly on a verifying signature;GMCRYPTO_ERRon invalid or any error (indistinguishable by design). - gmcrypto_
x509_ ⚠certificate_ verify_ signature_ with_ id - As
gmcrypto_x509_certificate_verify_signaturewith a caller-supplied SM2 signer ID;id_len == 0selects the default ID (the v1.2 KX convention — an empty ID is unrepresentable through this ABI). - gmcrypto_
x509_ ⚠verify_ chain - Verify a single linear, leaf-first certificate chain links to a
caller-trusted anchor.
chain/anchorsare arrays of cert handles;at_time(NULL = skip the validity window) is the comparison time; theboolverdict is written to*out_verified(1 = verifies, 0 = does not, e.g. over-depth). ReturnsGMCRYPTO_OKfor a successful evaluation,GMCRYPTO_ERRonly on NULLout_verifiedor a malformed handle array.
Type Aliases§
- gmcrypto_
rng_ callback - C ABI function pointer for caller-supplied RNG. Returns
0on success and non-zero on failure. See module-level docs for the full contract.