Skip to main content

Crate gmcrypto_c

Crate gmcrypto_c 

Source
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 a size_t where 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_new samples the ephemeral internally and writes R_A immediately, so no pre-ephemeral state exists in C. Pair with exactly one gmcrypto_sm2_kx_initiator_confirm (which consumes + frees) or one gmcrypto_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_newgmcrypto_sm2_kx_responder_respond (takes R_A, emits R_B + S_B) → gmcrypto_sm2_kx_responder_finish (takes S_A, releases K, consumes + frees). Pair with exactly one _finish or one gmcrypto_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_finalize confirms 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 via gmcrypto_sm4_cbc_encryptor_update, emit the trailing PKCS#7- padded block(s) via gmcrypto_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_update buffers ciphertext and emits nothing; gmcrypto_sm4_gcm_decryptor_finalize_verify releases the full plaintext only after a constant-time tag check. Memory is O(message). Construct with gmcrypto_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_update emits the ciphertext for its chunk; gmcrypto_sm4_gcm_encryptor_finalize emits the 16-byte tag. Construct with gmcrypto_sm4_gcm_encryptor_new; pair with exactly one finalize (which frees the handle) or one gmcrypto_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 with gmcrypto_tlcp_record_keys_cbc_new; free + wipe with gmcrypto_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 with gmcrypto_x509_certificate_free.
gmcrypto_x509_time_t
A certificate validity timestamp — plain calendar fields, mirroring the Rust X509Time exactly (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_B are SM3 digests; v1.2). Ephemeral points R_A / R_B use GMCRYPTO_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_data length (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). version is 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_chain accepts.

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 data into 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_OK on match; GMCRYPTO_ERR on mismatch. The handle is freed by this call.
gmcrypto_pbkdf2_hmac_sm3
Derive out_len bytes via PBKDF2-HMAC-SM3 over (pwd, salt, iterations). Writes into the caller-supplied out buffer.
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 || C3 ciphertext. Decrypt-only — there is no emit path for the legacy ordering, and there will not be one in any v0.5+ version (per CLAUDE.md “Don’t” entry).
gmcrypto_sm2_decrypt_c1c3c2
SM2 private-key decrypt of a modern raw byte-concat C1 || C3 || C2 ciphertext. Input length must be at least 65 + 32 + 1 = 98 bytes (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 || C2 format. C1 is the 65-byte SEC1-uncompressed point (0x04 || X || Y); C3 is the 32-byte SM3 MAC; C2 is msg_len bytes of XOR-ed ciphertext. Output length is exactly 65 + 32 + msg_len.
gmcrypto_sm2_encrypt_with_rng
_with_rng variant of gmcrypto_sm2_encrypt. Identical contract except RNG bytes come from the caller’s rng_callback rather than getrandom::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 (exactly klen bytes, the klen given at _new) to key_out and the initiator’s confirmation tag S_A (GMCRYPTO_SM2_KX_CONFIRM_SIZE = 32 bytes) to out_s_a — send S_A to the responder. r_b is the responder’s ephemeral point (65 bytes); s_b its 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_t handle on every path; takes only the peer R_B (65 bytes, SEC1 04 ‖ X ‖ Y) and writes the agreed key (the klen given at _new) to key_out. An invalid R_B is the single GMCRYPTO_ERR. The caller owns wiping key_out. Do NOT _free afterwards.
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 uncompressed 04 ‖ X ‖ Y, exactly GMCRYPTO_SM2_SEC1_UNCOMPRESSED_SIZE = 65 bytes) to out_r_a. The handle is created already awaiting the responder’s reply: send out_r_a to the responder, then call gmcrypto_sm2_kx_initiator_confirm with its (R_B, S_B).
gmcrypto_sm2_kx_initiator_new_with_rng
_with_rng variant of gmcrypto_sm2_kx_initiator_new: identical contract except the ephemeral randomness comes from the caller’s rng_callback (the v0.5 gmcrypto_rng_callback shape) rather than getrandom::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 (exactly klen bytes, the klen given at _new) to key_out.
gmcrypto_sm2_kx_responder_free
Free an UNCONSUMED responder handle (abandonment path — e.g. the initiator never confirmed, or a _respond failure 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_privkey is B’s static key; peer_pubkey is A’s static public key; ids and klen follow the gmcrypto_sm2_kx_initiator_new conventions (and must match the initiator’s, or the confirmation tags will not verify). The handle then waits for the initiator’s R_A — call gmcrypto_sm2_kx_responder_respond.
gmcrypto_sm2_kx_responder_respond
Receive the initiator’s R_A (65 bytes) and produce the responder’s reply: writes R_B (65 bytes) to out_r_b and the responder’s confirmation tag S_B (32 bytes) to out_s_b — send both to the initiator, then call gmcrypto_sm2_kx_responder_finish with its S_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), writes R_B (65 bytes) to out_r_b and the agreed key (klen bytes) to key_out. Ephemeral randomness comes from the OS. The caller owns wiping key_out. Do NOT _free afterwards.
gmcrypto_sm2_kx_responder_respond_unconfirmed_with_rng
_with_rng variant of gmcrypto_sm2_kx_responder_respond_unconfirmed: the ephemeral randomness comes from rng_callback rather than the OS. A NULL callback returns GMCRYPTO_ERR WITHOUT consuming the handle (free it yourself), matching the confirmed _with_rng flow.
gmcrypto_sm2_kx_responder_respond_with_rng
_with_rng variant of gmcrypto_sm2_kx_responder_respond: identical contract except the ephemeral randomness comes from the caller’s rng_callback rather than getrandom::SysRng.
gmcrypto_sm2_privkey_free
Free an SM2 private key. NULL is a no-op. The inner scalar is zeroized via ZeroizeOnDrop before 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_key and returns GMCRYPTO_OK. Caller MUST free via gmcrypto_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 msg with the SM2 private key using the supplied signer_id (or DEFAULT_SIGNER_ID = "1234567812345678" if signer_id_len == 0). Output is DER-encoded SEQUENCE { r, s }. RNG is sourced from getrandom::SysRng.
gmcrypto_sm2_sign_with_rng
_with_rng variant of gmcrypto_sm2_sign. Identical contract except RNG bytes come from the caller’s rng_callback rather than getrandom::SysRng.
gmcrypto_sm2_verify
Verify a DER-encoded (r, s) signature against msg using the SM2 public key and signer_id. Returns GMCRYPTO_OK on valid; GMCRYPTO_ERR on 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 call gmcrypto_sm3_free on 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 data into the streaming SM3 hasher.
gmcrypto_sm4_cbc_decrypt
SM4-CBC single-shot decrypt. Single-Failed return 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_free on 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. key is exactly 16 bytes; iv is 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 _finalize validates the trailing padding (buffer-back-by-one padding-oracle defense). Same buffer- size contract as the encryptor’s _update: caller MUST allocate out_capacity >= ct_len + 16 (strict upper bound on bytes emitted in one call). On insufficient capacity returns GMCRYPTO_ERR and 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_free on 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. key is exactly 16 bytes; iv is 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 out buffer MUST be at least pt_len + 16 bytes — that is the upper bound on bytes emitted by a single _update call (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 returns GMCRYPTO_ERR and 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 ct is ct_len bytes (ciphertext ‖ tag); tag_len must match the value used at encrypt time. pt_out receives ct_len - tag_len bytes. GMCRYPTO_ERR on any failure (single failure mode).
gmcrypto_sm4_ccm_encrypt
SM4-CCM single-shot encrypt. tag_len must be in {4, 6, 8, 10, 12, 14, 16}; nonce_len in [7, 13]. out receives pt_len + tag_len bytes (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_out receives ct_len bytes. Returns GMCRYPTO_OK only if the tag verifies; GMCRYPTO_ERR on any failure (single failure mode).
gmcrypto_sm4_gcm_decrypt_with_tag_len
SM4-GCM decrypt with a truncated tag. tag is tag_len bytes; tag_len must be in {4, 8, 12, 13, 14, 15, 16}. pt_out receives ct_len bytes. GMCRYPTO_ERR on any failure.
gmcrypto_sm4_gcm_decryptor_finalize_verify
Verify tag (tag_len bytes; 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_len bytes of ciphertext and fold them into the running GHASH. Emits no plaintext (commit-on-verify) — there is no output parameter. Returns GMCRYPTO_ERR only on null handle or invalid input pointer; a length-ceiling overflow is latched and surfaces as GMCRYPTO_ERR at gmcrypto_sm4_gcm_decryptor_finalize_verify.
gmcrypto_sm4_gcm_encrypt
SM4-GCM single-shot encrypt. ct_out receives pt_len bytes (via the capacity/actual-len convention); tag_out receives exactly 16 bytes. Returns GMCRYPTO_OK / GMCRYPTO_ERR.
gmcrypto_sm4_gcm_encrypt_with_tag_len
SM4-GCM encrypt with a truncated tag. tag_len must be in {4, 8, 12, 13, 14, 15, 16}; tag_out receives tag_len bytes. Invalid tag_lenGMCRYPTO_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_free on it afterwards. tag_out must be valid for exactly 16 bytes.
gmcrypto_sm4_gcm_encryptor_finalize_with_tag_len
Finish and emit a truncated tag of tag_len bytes (MSB_t per NIST SP 800-38D §5.2.1.2). tag_len must be in {4, 8, 12, 13, 14, 15, 16} (else GMCRYPTO_ERR). Consumes the encryptor — the handle is freed by this call (even on error); do NOT call gmcrypto_sm4_gcm_encryptor_free afterwards.
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. key is exactly 16 bytes; nonce is nonce_len bytes (12 = canonical; other lengths invoke the extra GHASH J0-derivation per NIST SP 800-38D §8.2.2); aad is 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_len bytes of plaintext, emitting the ciphertext for this chunk (length == pt_len; GCM does not pad or buffer). The out buffer MUST be at least pt_len bytes; on insufficient capacity returns GMCRYPTO_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). Returns GMCRYPTO_ERR once the cumulative plaintext would exceed the GCM ceiling (2^36 − 32 bytes); the encryptor is poisoned and all later calls also return GMCRYPTO_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 of gmcrypto_sm4_xts_encrypt with the same argument shape; out receives data_len bytes. Returns GMCRYPTO_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 of gmcrypto_sm4_xts_encrypt_sectors under the same (key, sector_size, start_sector); same in-place contract, single failure mode, and buf-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). key is exactly GMCRYPTO_SM4_XTS_KEY_SIZE (32) bytes (Key1 ‖ Key2); tweak is exactly GMCRYPTO_SM4_BLOCK_SIZE (16) raw bytes (the data-unit/sector identifier — caller-unique per key). out receives data_len bytes (length-preserving) via the capacity/actual-len convention. Returns GMCRYPTO_OK / GMCRYPTO_ERR (single failure mode: data_len outside [16, 16 MiB], Key1 == Key2, null pointer, or buffer too small — in which case *out_actual_len is 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). key is exactly GMCRYPTO_SM4_XTS_KEY_SIZE (32) bytes (Key1 ‖ Key2); buf is a contiguous run of buf_len / sector_size equal-size sectors transformed in place (buf_len must be a whole multiple of sector_size). Sector i is 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_sector is a uint64_t (LBA width), so the addressable range is [0, 2^64 − 1]; for the full u128 sector space use the Rust mode_xts::encrypt_sectors API. Returns GMCRYPTO_OK / GMCRYPTO_ERR (single failure mode: sector_size outside [16, 16 MiB] or not a multiple of 16, buf_len not a whole multiple of sector_size, Key1 == Key2, or null pointer). buf is untouched on GMCRYPTO_ERR. buf_len == 0 is a vacuous GMCRYPTO_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 single GMCRYPTO_ERR and 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 single GMCRYPTO_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 exactly out_len bytes (the caller carves per suite — CBC 128, GCM 40). out_len == 0 is vacuously OK. The caller owns wiping out.
gmcrypto_tlcp_derive_master_secret
Derive the 48-byte TLCP master secret from a 48-byte pre_master and the two 32-byte randoms. Infallible in core — returns GMCRYPTO_ERR only on a NULL pointer. The caller owns wiping pre_master and out.
gmcrypto_tlcp_finished_verify_data
Compute the 12-byte Finished verify_data for role (0 = Client, 1 = Server). transcript_hash is the caller’s SM3 over the handshake messages (stateless). The caller owns wiping out.
gmcrypto_tlcp_protect_cbc
Protect (MAC-then-encrypt) a plaintext record under SM4-CBC with HMAC-SM3, a fresh OS-sampled explicit IV. version is 2 bytes; output to the (out, out_capacity, out_actual_len) copy-out buffer. Single GMCRYPTO_ERR. (key, seq) uniqueness is the caller’s contract.
gmcrypto_tlcp_protect_cbc_with_rng
_with_rng variant of gmcrypto_tlcp_protect_cbc: the explicit IV comes from rng_callback (REQUIRED for record-KAT reproduction) rather than the OS. A NULL callback returns GMCRYPTO_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 with gmcrypto_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 role from a 40-byte (GMCRYPTO_TLCP_GCM_KEY_BLOCK_LEN) key block. Returns NULL on a bad role / NULL block. Free with gmcrypto_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. Returns GMCRYPTO_ERR only on NULL out_verified or a malformed handle array.
gmcrypto_version
Returns a NUL-terminated string with the gmcrypto-c crate version, tracking Cargo’s CARGO_PKG_VERSION at build time (e.g. "1.0.0"). The returned pointer is to a static &'static CStr and must NOT be freed by the caller.
gmcrypto_x509_certificate_basic_constraints
Read the basicConstraints extension. Writes 1/0 to *out_present (absent/malformed → 0), the cA flag to *out_is_ca, and the pathLenConstraint to *out_path_len guarded by *out_has_path_len (parsed, not enforced — informational). Returns GMCRYPTO_ERR only on NULL.
gmcrypto_x509_certificate_extensions_raw
The Extensions SEQUENCE TLV if present — shape-checked at parse but NEVER interpreted (critical flags included); a caller building trust logic on top inherits RFC 5280 §4.2’s reject-unrecognized-critical obligation. *out_actual_len == 0 means the optional extensions block is ABSENT (a present block is never empty), with GMCRYPTO_OK. Copy-out convention otherwise as gmcrypto_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-sm3 signature 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 — see gmcrypto-core’s x509 module docs).
gmcrypto_x509_certificate_is_self_issued
Write 1 to *out_is_self_issued if the certificate’s subject and issuer Names are byte-identical (the RFC 5280 self-ISSUED notion), else 0; returns GMCRYPTO_OK for a successful evaluation, GMCRYPTO_ERR on null/bad arguments (“not self-issued” is NOT a failure). NOT “self-signed”: use gmcrypto_x509_certificate_verify_signature against the cert’s own subject key for a self-signature check.
gmcrypto_x509_certificate_issuer_raw
The issuer Name as its full raw DER TLV — no interpretation; match issuers by byte equality. Copy-out convention as gmcrypto_x509_certificate_tbs_raw.
gmcrypto_x509_certificate_key_usage
Read the keyUsage extension. Writes 1/0 to *out_present (absent OR malformed → 0) and the raw bitmask to *out_bits (bit 0 = digitalSignature). Returns GMCRYPTO_ERR only on NULL.
gmcrypto_x509_certificate_not_after
Write the certificate’s notAfter into *out_time. Exposure only — NO validity decision is made (see gmcrypto_x509_time_t).
gmcrypto_x509_certificate_not_before
Write the certificate’s notBefore into *out_time. Exposure only — NO validity decision is made (see gmcrypto_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 with gmcrypto_sm2_verify / gmcrypto_sm2_encrypt / the KX constructors — and with gmcrypto_x509_certificate_verify_signature for 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 Name as its full raw DER TLV — no interpretation. Copy-out convention as gmcrypto_x509_certificate_tbs_raw.
gmcrypto_x509_certificate_tbs_raw
The exact TBSCertificate TLV 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 tbsCertificate bytes against the issuer’s public key (issuer_pubkey is a KEY handle, not an issuer certificate), using the GM / RFC 8998 default signer ID "1234567812345678". Returns GMCRYPTO_OK only on a verifying signature; GMCRYPTO_ERR on invalid or any error (indistinguishable by design).
gmcrypto_x509_certificate_verify_signature_with_id
As gmcrypto_x509_certificate_verify_signature with a caller-supplied SM2 signer ID; id_len == 0 selects 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 / anchors are arrays of cert handles; at_time (NULL = skip the validity window) is the comparison time; the bool verdict is written to *out_verified (1 = verifies, 0 = does not, e.g. over-depth). Returns GMCRYPTO_OK for a successful evaluation, GMCRYPTO_ERR only on NULL out_verified or a malformed handle array.

Type Aliases§

gmcrypto_rng_callback
C ABI function pointer for caller-supplied RNG. Returns 0 on success and non-zero on failure. See module-level docs for the full contract.