How to use pQCee TEE API Server ================================ The server handles Web APIs i.e. POST and GET requests for the various cryptographic operations. Request Method is GET when no parameters are needed, and POST when parameters are needed. Server Initialisation --------------------- The server needs a Transport Key to encrypt all private keys before returning. "Initialisation" of the server refers to the process of loading a Transport Key into the server. There are two ways to initialise the server. #. Loading the Transport Key through an API call. The Initialise Server operation returns an encapsulation key that derives a symmetric key. The administrator encrypts the Transport Key with this key before loading it into the server. #. Typing the Transport Key on server start. The administrator types the Transport Key into the terminal when the server starts. In this case, the administrator does not call the initialise server operation. Overview of APIs -------------------- pQCee's Trusted Execution Environment (TEE) API server consist of: - 2 functions that achieves a quantum-safe Transport Key Setup process, - 3 functions that achieves the ML-KEM cryptographic functions, and - 3 functions that achieves the SPP-ECDSA cryptographic functions. - 3 functions that achieves the ML-DSA cryptographic functions. Transport Key Setup using API ############################## #. Call the :ref:`init_server` API to receive an ML-KEM-768 Encapsulation Key. #. On your own server, encapsulate this key, and use the resulting "shared secret" to encrypt the Transport Key. #. Pass the encrypted transport key and ML-KEM-768 ciphertext to the :ref:`load_tk` API to transfer the Transport Key into the API server. ML-KEM Cryptographic Functions ############################## #. To obtain a new ML-KEM-768 keypair, call the :ref:`mlkem_keygen` API to receive an Encapsulation Key and an encrypted Decapsulation Key. The Decapsulation Key is encrypted with an Ephemeral Key derived from the Transport Key. #. On your own server, encapsulate the Encapsulation Key, and use the resulting "shared secret" to encrypt the data. #. Pass the encrypted data, encrypted Decapsulation Key and ML-KEM-768 ciphertext to the :ref:`mlkem_decrypt` API to receive the decrypted data. #. Pass the data, encrypted Decapsulation Key and ML-KEM-768 ciphertext to the :ref:`tofrontdecrypt` API to receive the encrypted data. SPP-ECDSA Cryptographic Functions ################################### #. To obtain a new SPP-ECDSA keypair, call the :ref:`keygen` API to receive an encrypted SPP secret key and its ECDSA public key. The SPP secret key is encrypted with an Ephemeral Key derived from the Transport Key. #. Hash the data you wish to sign using SHA256, resulting in a "digest". #. Call the :ref:`sign` API with the encrypted SPP secret key and this "digest" to receive an SPP-ECDSA signature and its zero-knowledge proof. #. Call the :ref:`verify` API with the "digest", the signature, the ECDSA public key and the zero-knowledge proof to verify the authenticity of the signature. ML-DSA Cryptographic Functions ################################### #. To obtain a new ML-DSA keypair, call the :ref:`mldsa_keygen` API to receive an encrypted ML-DSA private key and its public key. The ML-DSA private key is encrypted with an Ephemeral Key derived from the Transport Key. #. Call the :ref:`mldsa_sign` API with the encrypted SPP secret key, context and the "message" to receive a detached ML-DSA signature. #. Call the :ref:`mldsa_verify` API with the "message", the signature, the ML-DSA public key and the context to verify the authenticity of the signature. Example Usage ------------------------------- The following script provides an example usage of the API server. - The linux ``curl`` program is used to make GET and POST requests to the server. - ``curl`` commands without any parameters are GET requests, while ``curl`` commands with ``--header`` and ``--data-binary`` are POST requests. - Parameters to the POST requests are JSON objects, here processed by the JSON processing tool ``jq``. .. code-block:: bash set -e ADDR="http://localhost:8443" echo "------------init_server()------------" curl -v ${ADDR}/init_server | tee mlkem_encap_key | jq echo "----------loadTK(E_SS(TK), CT)----------" cat ciphertext encrypted_tk | jq -sc add >to_loadtk curl -v ${ADDR}/load_tk --header "Content-Type: application/json" --data-binary @to_loadtk echo "------------mlkem_keygen()------------" curl -v ${ADDR}/mlkem_keygen >mlkem_keys echo "Split into encrypted_mlkem_decap_key and mlkem_encap_key" jq '{encrypted_mlkem_decap_key: .encrypted_mlkem_decap_key}' mlkem_keys >encrypted_mlkem_decap_key jq '{mlkem_encap_key: .mlkem_encap_key}' mlkem_keys >mlkem_encap_key echo "------------mlkem_decrypt(E_SS2(data), E_EK(mlkem_decap_key), CT)------------" cat encrypted_mlkem_decap_key ciphertext encrypted_data | jq -sc add >to_mlkemdecrypt echo "Running ML-KEM Decrypt" curl -v ${ADDR}/mlkem_decrypt --header "Content-Type: application/json" --data-binary @to_mlkemdecrypt | tee data | jq echo "------------keygen()------------" curl -v ${ADDR}/keygen >keys echo "Split into encrypted_secret_key and public_key" jq '{encrypted_secret_key: .encrypted_secret_key}' keys >encrypted_secret_key jq '{public_key: .public_key}' keys >public_key echo "Create input params to sign" cat encrypted_secret_key public_key digest | jq -s add >to_sign echo "------------sign(digest, E_EK(secretkey), publickey)------------" curl -v ${ADDR}/sign --header "Content-Type: application/json" --data-binary @to_sign | jq >signed echo "Create input params to verify" cat public_key digest signed | jq -s add >to_verify echo "------------verify(digest, signature, proof, publickey)------------" curl -v ${ADDR}/verify --header "Content-Type: application/json" --data-binary @to_verify echo "------------mldsa_keygen()------------" curl -v ${ADDR}/mldsa_keygen >mldsa_keys echo "Split into encrypted_mldsa_private_key and mldsa_public_key" jq '{encrypted_mldsa_private_key: .encrypted_mldsa_private_key}' mldsa_keys >encrypted_mldsa_private_key jq '{mldsa_public_key: .mldsa_public_key}' mldsa_keys >mldsa_public_key echo "Create input params to mldsa_sign" cat encrypted_mldsa_private_key message context | jq -s add >to_mldsa_sign echo "------------mldsa_sign(message, E_EK(privatekey), context)------------" curl -v ${ADDR}/mldsa_sign --header "Content-Type: application/json" --data-binary @to_mldsa_sign | jq >mldsa_signed echo "Create input params to mldsa_verify" cat mldsa_public_key message mldsa_signed context | jq -s add >to_mldsa_verify echo "------------mldsa_verify(message, mlsignature, mldsa_public_key, context)------------" curl -v ${ADDR}/mldsa_verify --header "Content-Type: application/json" --data-binary @to_mldsa_verify