### Setup HMAC-PRNG Source: https://context7.com/intel/tinycrypt/llms.txt Initializes and seeds the HMAC-PRNG for cryptographically secure pseudo-random number generation. Requires a personalization string and entropy source. The PRNG may require reseeding. ```c #include #include #include int setup_prng(struct tc_hmac_prng_struct *prng, const uint8_t *personalization, unsigned int plen, const uint8_t *entropy, unsigned int entropy_len) { /* Initialize PRNG with personalization string (required, non-null) */ if (tc_hmac_prng_init(prng, personalization, plen) != TC_CRYPTO_SUCCESS) { return -1; } /* Seed with entropy (required after init) */ if (tc_hmac_prng_reseed(prng, entropy, entropy_len, NULL, 0) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } int generate_random(struct tc_hmac_prng_struct *prng, uint8_t *output, unsigned int output_len) { int result = tc_hmac_prng_generate(output, output_len, prng); if (result == TC_HMAC_PRNG_RESEED_REQ) { /* PRNG needs reseeding before generating more data */ return -2; } if (result != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { struct tc_hmac_prng_struct prng; const char *personalization = "my_device_hostname_20231201"; uint8_t entropy[32]; /* Must come from a true entropy source */ uint8_t random_bytes[64]; /* Get entropy from hardware RNG or other source */ /* ... fill entropy[] with random data ... */ setup_prng(&prng, (const uint8_t *)personalization, strlen(personalization), entropy, sizeof(entropy)); generate_random(&prng, random_bytes, sizeof(random_bytes)); return 0; } ``` -------------------------------- ### Build and Link TinyCrypt Library Source: https://context7.com/intel/tinycrypt/llms.txt Commands to compile the library, run tests, and link specific primitives into a C application. ```bash # Clone or download TinyCrypt # Configure lib/Makefile to select desired primitives # Build the library make # Run tests cd tests && make && ./test_sha256 && ./test_aes && ./test_hmac # Link in your application gcc -I/path/to/tinycrypt/lib/include your_app.c \ /path/to/tinycrypt/lib/source/sha256.c \ /path/to/tinycrypt/lib/source/hmac.c \ -o your_app ``` -------------------------------- ### Compute SHA-256 Hash in C Source: https://context7.com/intel/tinycrypt/llms.txt Demonstrates initializing the SHA-256 state, updating with message data, and finalizing the digest calculation. ```c #include #include int compute_sha256_hash(const uint8_t *message, size_t msg_len, uint8_t *digest) { struct tc_sha256_state_struct state; /* Initialize the SHA-256 state */ if (tc_sha256_init(&state) != TC_CRYPTO_SUCCESS) { return -1; } /* Process the message data - can be called multiple times for large data */ if (tc_sha256_update(&state, message, msg_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Finalize and output the 32-byte digest */ if (tc_sha256_final(digest, &state) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const char *message = "abc"; uint8_t digest[TC_SHA256_DIGEST_SIZE]; /* 32 bytes */ compute_sha256_hash((const uint8_t *)message, strlen(message), digest); /* Expected digest: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad */ return 0; } ``` -------------------------------- ### Initialize and Generate Random Numbers with CTR-PRNG Source: https://context7.com/intel/tinycrypt/llms.txt Requires at least 32 bytes of entropy for initialization. The generator must be uninstantiated after use to clear sensitive state. ```c #include #include #include int setup_ctr_prng(TCCtrPrng_t *prng, const uint8_t *entropy, unsigned int entropy_len, const uint8_t *personalization, unsigned int plen) { /* Initialize: entropy must be at least TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE (32 bytes) */ if (tc_ctr_prng_init(prng, entropy, entropy_len, personalization, plen) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } int generate_ctr_random(TCCtrPrng_t *prng, uint8_t *output, unsigned int output_len) { int result = tc_ctr_prng_generate(prng, NULL, 0, output, output_len); if (result == TC_CTR_PRNG_RESEED_REQ) { return -2; /* Needs reseeding */ } if (result != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { TCCtrPrng_t prng; uint8_t entropy[32]; /* Minimum required size */ const char *personalization = "device_session_001"; uint8_t random_bytes[128]; /* Fill entropy from hardware source */ setup_ctr_prng(&prng, entropy, sizeof(entropy), (const uint8_t *)personalization, strlen(personalization)); generate_ctr_random(&prng, random_bytes, sizeof(random_bytes)); /* Clean up sensitive state when done */ tc_ctr_prng_uninstantiate(&prng); return 0; } ``` -------------------------------- ### Compute HMAC-SHA256 Authentication Tag in C Source: https://context7.com/intel/tinycrypt/llms.txt Shows how to configure an HMAC state with a secret key and generate an authentication tag for a given message. ```c #include #include #include int compute_hmac_tag(const uint8_t *key, unsigned int key_len, const uint8_t *message, unsigned int msg_len, uint8_t *tag) { struct tc_hmac_state_struct hmac_state; memset(&hmac_state, 0, sizeof(hmac_state)); /* Configure HMAC with the secret key */ if (tc_hmac_set_key(&hmac_state, key, key_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Initialize for a new HMAC computation */ if (tc_hmac_init(&hmac_state) != TC_CRYPTO_SUCCESS) { return -1; } /* Process the message - can be called multiple times */ if (tc_hmac_update(&hmac_state, message, msg_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Finalize and output the 32-byte tag */ if (tc_hmac_final(tag, TC_SHA256_DIGEST_SIZE, &hmac_state) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const uint8_t key[20] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; const char *data = "Hi There"; uint8_t tag[TC_SHA256_DIGEST_SIZE]; compute_hmac_tag(key, sizeof(key), (const uint8_t *)data, strlen(data), tag); /* RFC 4231 test vector result */ return 0; } ``` -------------------------------- ### Implement ECC-DSA Sign and Verify in C Source: https://context7.com/intel/tinycrypt/llms.txt Provides functions to sign and verify messages using the NIST p-256 curve. Requires an RNG to be configured via uECC_set_rng before signing. ```c #include #include #include #include #include int sign_message(const uint8_t *private_key, const uint8_t *message, size_t msg_len, uint8_t *signature) { const struct uECC_Curve_t *curve = uECC_secp256r1(); uint8_t hash[TC_SHA256_DIGEST_SIZE]; struct tc_sha256_state_struct sha_state; /* Hash the message first */ tc_sha256_init(&sha_state); tc_sha256_update(&sha_state, message, msg_len); tc_sha256_final(hash, &sha_state); /* Sign the hash - requires RNG to be set via uECC_set_rng() */ if (uECC_sign(private_key, hash, sizeof(hash), signature, curve) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } int verify_signature(const uint8_t *public_key, const uint8_t *message, size_t msg_len, const uint8_t *signature) { const struct uECC_Curve_t *curve = uECC_secp256r1(); uint8_t hash[TC_SHA256_DIGEST_SIZE]; struct tc_sha256_state_struct sha_state; /* Hash the message */ tc_sha256_init(&sha_state); tc_sha256_update(&sha_state, message, msg_len); tc_sha256_final(hash, &sha_state); /* Verify the signature */ if (uECC_verify(public_key, hash, sizeof(hash), signature, curve) != TC_CRYPTO_SUCCESS) { return -1; /* Signature invalid */ } return 0; /* Signature valid */ } /* Example usage */ int main(void) { const struct uECC_Curve_t *curve = uECC_secp256r1(); uint8_t private_key[32]; uint8_t public_key[64]; uint8_t signature[64]; const char *message = "Document to sign"; /* Set RNG and generate key pair */ uECC_set_rng(default_CSPRNG); uECC_make_key(public_key, private_key, curve); /* Sign the message */ sign_message(private_key, (const uint8_t *)message, strlen(message), signature); /* Verify the signature */ if (verify_signature(public_key, (const uint8_t *)message, strlen(message), signature) == 0) { /* Signature is valid */ } return 0; } ``` -------------------------------- ### AES-CBC Mode Encryption and Decryption Source: https://context7.com/intel/tinycrypt/llms.txt Encrypts and decrypts data using AES in Cipher Block Chaining (CBC) mode. Requires a key and an Initialization Vector (IV). The IV is prepended to the ciphertext. ```c #include #include #include int aes_cbc_encrypt(const uint8_t *key, const uint8_t *iv, const uint8_t *plaintext, unsigned int plaintext_len, uint8_t *ciphertext) { struct tc_aes_key_sched_struct key_schedule; /* Set up encryption key schedule */ tc_aes128_set_encrypt_key(&key_schedule, key); /* Encrypt: ciphertext buffer must be plaintext_len + TC_AES_BLOCK_SIZE * The IV is prepended to the ciphertext */ if (tc_cbc_mode_encrypt(ciphertext, plaintext_len + TC_AES_BLOCK_SIZE, plaintext, plaintext_len, iv, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } int aes_cbc_decrypt(const uint8_t *key, const uint8_t *ciphertext, unsigned int ciphertext_len, uint8_t *plaintext) { struct tc_aes_key_sched_struct key_schedule; const uint8_t *iv = ciphertext; /* IV is prepended to ciphertext */ const uint8_t *encrypted_data = ciphertext + TC_AES_BLOCK_SIZE; /* Set up decryption key schedule */ tc_aes128_set_decrypt_key(&key_schedule, key); /* Decrypt */ if (tc_cbc_mode_decrypt(plaintext, ciphertext_len, encrypted_data, ciphertext_len, iv, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const uint8_t key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; const uint8_t iv[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; uint8_t plaintext[64] = { /* 4 blocks of test data */ }; uint8_t ciphertext[80]; /* plaintext + IV */ uint8_t decrypted[64]; aes_cbc_encrypt(key, iv, plaintext, sizeof(plaintext), ciphertext); aes_cbc_decrypt(key, ciphertext, sizeof(ciphertext), decrypted); return 0; } ``` -------------------------------- ### AES-128 Block Encryption and Decryption Source: https://context7.com/intel/tinycrypt/llms.txt Encrypts and decrypts a single 16-byte block using AES-128. Requires setting up an AES key schedule before performing the operation. ```c #include #include int aes128_encrypt_block(const uint8_t *key, const uint8_t *plaintext, uint8_t *ciphertext) { struct tc_aes_key_sched_struct key_schedule; /* Initialize the key schedule for encryption */ if (tc_aes128_set_encrypt_key(&key_schedule, key) != TC_CRYPTO_SUCCESS) { return -1; } /* Encrypt a single 16-byte block */ if (tc_aes_encrypt(ciphertext, plaintext, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } int aes128_decrypt_block(const uint8_t *key, const uint8_t *ciphertext, uint8_t *plaintext) { struct tc_aes_key_sched_struct key_schedule; /* Initialize the key schedule for decryption */ if (tc_aes128_set_decrypt_key(&key_schedule, key) != TC_CRYPTO_SUCCESS) { return -1; } /* Decrypt a single 16-byte block */ if (tc_aes_decrypt(plaintext, ciphertext, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const uint8_t key[TC_AES_KEY_SIZE] = { /* 16 bytes */ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; const uint8_t plaintext[TC_AES_BLOCK_SIZE] = { /* 16 bytes */ 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; uint8_t ciphertext[TC_AES_BLOCK_SIZE]; uint8_t decrypted[TC_AES_BLOCK_SIZE]; aes128_encrypt_block(key, plaintext, ciphertext); aes128_decrypt_block(key, ciphertext, decrypted); return 0; } ``` -------------------------------- ### AES-CCM Mode Decryption and Verification Source: https://context7.com/intel/tinycrypt/llms.txt Decrypts data and verifies the authentication tag using AES-CCM mode. Requires the same key, nonce, MAC length, and associated data used during encryption. Authentication failure will result in an error. ```c #include #include int aes_ccm_decrypt(const uint8_t *key, uint8_t *nonce, unsigned int mac_len, const uint8_t *aad, unsigned int aad_len, const uint8_t *ciphertext, unsigned int ciphertext_len, uint8_t *plaintext) { struct tc_ccm_mode_struct ccm; struct tc_aes_key_sched_struct key_schedule; tc_aes128_set_encrypt_key(&key_schedule, key); if (tc_ccm_config(&ccm, &key_schedule, nonce, 13, mac_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Decrypt and verify authentication tag */ if (tc_ccm_decryption_verification(plaintext, ciphertext_len - mac_len, aad, aad_len, ciphertext, ciphertext_len, &ccm) != TC_CRYPTO_SUCCESS) { return -1; /* Authentication failed or decryption error */ } return 0; } /* Example usage */ int main(void) { const uint8_t key[16] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}; uint8_t nonce[13] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c}; const uint8_t aad[] = "associated data"; uint8_t plaintext[32] = "secret message to encrypt"; uint8_t ciphertext[32 + 8]; /* plaintext + 8-byte MAC */ uint8_t decrypted[32]; aes_ccm_encrypt(key, nonce, 8, aad, sizeof(aad)-1, plaintext, sizeof(plaintext), ciphertext); aes_ccm_decrypt(key, nonce, 8, aad, sizeof(aad)-1, ciphertext, sizeof(ciphertext), decrypted); return 0; } ``` -------------------------------- ### AES-CCM Mode Encryption Source: https://context7.com/intel/tinycrypt/llms.txt Encrypts data and generates an authentication tag using AES-CCM mode. Requires a nonce, associated data, and specifies the MAC length. The output includes both ciphertext and the authentication tag. ```c #include #include int aes_ccm_encrypt(const uint8_t *key, uint8_t *nonce, unsigned int mac_len, const uint8_t *aad, unsigned int aad_len, const uint8_t *plaintext, unsigned int plaintext_len, uint8_t *ciphertext) { struct tc_ccm_mode_struct ccm; struct tc_aes_key_sched_struct key_schedule; /* Set up the AES key */ tc_aes128_set_encrypt_key(&key_schedule, key); /* Configure CCM mode: nonce is 13 bytes, mac_len must be 4,6,8,10,12,14,or 16 */ if (tc_ccm_config(&ccm, &key_schedule, nonce, 13, mac_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Encrypt and generate authentication tag * Output size = plaintext_len + mac_len */ if (tc_ccm_generation_encryption(ciphertext, plaintext_len + mac_len, aad, aad_len, plaintext, plaintext_len, &ccm) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const uint8_t key[16] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}; uint8_t nonce[13] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c}; const uint8_t aad[] = "associated data"; uint8_t plaintext[32] = "secret message to encrypt"; uint8_t ciphertext[32 + 8]; /* plaintext + 8-byte MAC */ uint8_t decrypted[32]; aes_ccm_encrypt(key, nonce, 8, aad, sizeof(aad)-1, plaintext, sizeof(plaintext), ciphertext); aes_ccm_decrypt(key, nonce, 8, aad, sizeof(aad)-1, ciphertext, sizeof(ciphertext), decrypted); return 0; } ``` -------------------------------- ### Perform ECC-DH Key Exchange Source: https://context7.com/intel/tinycrypt/llms.txt Requires a cryptographically secure RNG function to be set via uECC_set_rng before generating keys. The resulting shared secrets should be processed with a KDF. ```c #include #include #include /* Required: Set up a cryptographically secure RNG before key generation */ int default_CSPRNG(uint8_t *dest, unsigned int size) { /* Implement using your platform's secure random source */ /* Return 1 on success, 0 on failure */ return 1; } int perform_ecdh_key_exchange(void) { const struct uECC_Curve_t *curve = uECC_secp256r1(); /* Alice's key pair */ uint8_t alice_private[32]; uint8_t alice_public[64]; /* Bob's key pair */ uint8_t bob_private[32]; uint8_t bob_public[64]; /* Shared secrets */ uint8_t alice_shared[32]; uint8_t bob_shared[32]; /* Set the RNG function (must be done before key generation) */ uECC_set_rng(default_CSPRNG); /* Generate key pairs */ if (uECC_make_key(alice_public, alice_private, curve) != TC_CRYPTO_SUCCESS) { return -1; } if (uECC_make_key(bob_public, bob_private, curve) != TC_CRYPTO_SUCCESS) { return -1; } /* Compute shared secrets */ if (uECC_shared_secret(bob_public, alice_private, alice_shared, curve) != TC_CRYPTO_SUCCESS) { return -1; } if (uECC_shared_secret(alice_public, bob_private, bob_shared, curve) != TC_CRYPTO_SUCCESS) { return -1; } /* alice_shared and bob_shared should be identical */ /* Use with a KDF (NIST SP 800-108) to derive symmetric keys */ return 0; } ``` -------------------------------- ### Compute AES-CMAC Tag Source: https://context7.com/intel/tinycrypt/llms.txt Computes a 16-byte authentication tag for a given message using AES-CMAC. Requires setting up the key schedule and CMAC state before processing the message and finalizing the tag. Sensitive state data should be erased afterward. ```c #include #include #include int compute_cmac(const uint8_t *key, const uint8_t *message, size_t msg_len, uint8_t *tag) { struct tc_cmac_struct cmac_state; struct tc_aes_key_sched_struct key_schedule; memset(&cmac_state, 0, sizeof(cmac_state)); /* Set up the AES key and CMAC state */ tc_aes128_set_encrypt_key(&key_schedule, key); if (tc_cmac_setup(&cmac_state, key, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } /* Initialize for a new CMAC computation */ if (tc_cmac_init(&cmac_state) != TC_CRYPTO_SUCCESS) { return -1; } /* Process the message - can be called multiple times */ if (tc_cmac_update(&cmac_state, message, msg_len) != TC_CRYPTO_SUCCESS) { return -1; } /* Finalize and output the 16-byte tag */ if (tc_cmac_final(tag, &cmac_state) != TC_CRYPTO_SUCCESS) { return -1; } /* Erase sensitive state data */ tc_cmac_erase(&cmac_state); return 0; } /* Example usage */ int main(void) { const uint8_t key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; const uint8_t message[] = "Message to authenticate with CMAC"; uint8_t tag[TC_AES_BLOCK_SIZE]; /* 16 bytes */ compute_cmac(key, message, sizeof(message)-1, tag); return 0; } ``` -------------------------------- ### AES-CTR Mode Encryption/Decryption Source: https://context7.com/intel/tinycrypt/llms.txt Encrypts or decrypts data using AES in Counter mode. The counter is modified in place, so a copy is needed if the original value is required later. This mode is suitable for data of any length. ```c #include #include #include int aes_ctr_crypt(const uint8_t *key, uint8_t *counter, const uint8_t *input, unsigned int input_len, uint8_t *output) { struct tc_aes_key_sched_struct key_schedule; /* Set up encryption key schedule (same for encrypt/decrypt) */ tc_aes128_set_encrypt_key(&key_schedule, key); /* CTR mode: same function for encrypt and decrypt * Counter is modified in place, so copy if reuse is needed */ if (tc_ctr_mode(output, input_len, input, input_len, counter, &key_schedule) != TC_CRYPTO_SUCCESS) { return -1; } return 0; } /* Example usage */ int main(void) { const uint8_t key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; uint8_t counter[16] = {0}; /* Initial counter value */ uint8_t plaintext[100] = "Message to encrypt with CTR mode"; uint8_t ciphertext[100]; uint8_t decrypted[100]; uint8_t counter_copy[16]; /* Encrypt */ memcpy(counter_copy, counter, 16); aes_ctr_crypt(key, counter_copy, plaintext, sizeof(plaintext), ciphertext); /* Decrypt - reset counter to original value */ memcpy(counter_copy, counter, 16); aes_ctr_crypt(key, counter_copy, ciphertext, sizeof(ciphertext), decrypted); return 0; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.