diff --git a/crypto/aes-modes/aes-cfb.c b/crypto/aes-modes/aes-cfb.c new file mode 100644 index 00000000..44aff5c0 --- /dev/null +++ b/crypto/aes-modes/aes-cfb.c @@ -0,0 +1,303 @@ +/* aes-cfb.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* AES-CFB Example + * This example demonstrates: + * - One-shot encryption using wc_AesCfbEncrypt() + * - Streaming decryption using wc_AesCfbDecrypt() in chunks + * Note: CFB mode inherently supports streaming (no padding required) + */ + +#include +#include +#include + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include + +#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB) + +#define AES_KEY_SIZE AES_256_KEY_SIZE + +/* Small chunk size to demonstrate streaming */ +#define CHUNK_SIZE 64 + +static int read_file(const char* filename, byte** data, word32* dataSz) +{ + FILE* fp; + long fileSz; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("Error: Cannot open file %s\n", filename); + return -1; + } + + fseek(fp, 0, SEEK_END); + fileSz = ftell(fp); + fseek(fp, 0, SEEK_SET); + + *data = (byte*)malloc(fileSz); + if (*data == NULL) { + fclose(fp); + printf("Error: Memory allocation failed\n"); + return -1; + } + + *dataSz = (word32)fread(*data, 1, fileSz, fp); + fclose(fp); + + return 0; +} + +static int write_file(const char* filename, const byte* data, word32 dataSz) +{ + FILE* fp; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + printf("Error: Cannot create file %s\n", filename); + return -1; + } + + fwrite(data, 1, dataSz, fp); + fclose(fp); + + return 0; +} + +/* One-shot encryption */ +static int encrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + WC_RNG rng; + byte iv[AES_BLOCK_SIZE]; + byte* plaintext = NULL; + byte* ciphertext = NULL; + word32 plaintextSz; + int ret; + + ret = read_file(inFile, &plaintext, &plaintextSz); + if (ret != 0) return ret; + + /* IV + ciphertext */ + ciphertext = (byte*)malloc(plaintextSz + AES_BLOCK_SIZE); + if (ciphertext == NULL) { + free(plaintext); + return -1; + } + + /* Generate random IV */ + ret = wc_InitRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); + wc_FreeRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(plaintext); + free(ciphertext); + return ret; + } + + /* One-shot encrypt */ + ret = wc_AesCfbEncrypt(&aes, ciphertext + AES_BLOCK_SIZE, plaintext, + plaintextSz); + wc_AesFree(&aes); + + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Prepend IV to output */ + memcpy(ciphertext, iv, AES_BLOCK_SIZE); + + ret = write_file(outFile, ciphertext, plaintextSz + AES_BLOCK_SIZE); + + free(plaintext); + free(ciphertext); + + printf("AES-CFB encryption complete (one-shot)\n"); + return ret; +} + +/* Streaming decryption - process in chunks */ +static int decrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + byte iv[AES_BLOCK_SIZE]; + byte* ciphertext = NULL; + byte* plaintext = NULL; + word32 ciphertextSz; + word32 plaintextSz; + word32 offset; + word32 chunkSz; + int ret; + + ret = read_file(inFile, &ciphertext, &ciphertextSz); + if (ret != 0) return ret; + + if (ciphertextSz < AES_BLOCK_SIZE) { + free(ciphertext); + printf("Error: File too small\n"); + return -1; + } + + /* Extract IV from beginning */ + memcpy(iv, ciphertext, AES_BLOCK_SIZE); + + plaintextSz = ciphertextSz - AES_BLOCK_SIZE; + plaintext = (byte*)malloc(plaintextSz); + if (plaintext == NULL) { + free(ciphertext); + return -1; + } + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(ciphertext); + free(plaintext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + /* Streaming decrypt - process in chunks */ + printf("AES-CFB streaming decryption:\n"); + offset = 0; + while (offset < plaintextSz) { + chunkSz = plaintextSz - offset; + if (chunkSz > CHUNK_SIZE) { + chunkSz = CHUNK_SIZE; + } + + ret = wc_AesCfbDecrypt(&aes, plaintext + offset, + ciphertext + AES_BLOCK_SIZE + offset, chunkSz); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + printf(" Decrypted chunk: offset=%u, size=%u\n", offset, chunkSz); + offset += chunkSz; + } + + wc_AesFree(&aes); + + ret = write_file(outFile, plaintext, plaintextSz); + + free(ciphertext); + free(plaintext); + + printf("AES-CFB decryption complete (streaming)\n"); + return ret; +} + +int main(int argc, char** argv) +{ + byte key[AES_KEY_SIZE]; + int ret; + + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + printf("Encrypts input file (one-shot), then decrypts to output file " + "(streaming)\n"); + return 1; + } + + wolfCrypt_Init(); + + /* Use a fixed key for demonstration */ + memset(key, 0x02, AES_KEY_SIZE); + + /* Encrypt to temporary file */ + ret = encrypt_file(argv[1], "temp_encrypted.bin", key, AES_KEY_SIZE); + if (ret != 0) { + printf("Encryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Decrypt to output file */ + ret = decrypt_file("temp_encrypted.bin", argv[2], key, AES_KEY_SIZE); + if (ret != 0) { + printf("Decryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Clean up temp file */ + remove("temp_encrypted.bin"); + + printf("Success! Decrypted file written to %s\n", argv[2]); + + wolfCrypt_Cleanup(); + return 0; +} + +#else + +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + printf("AES-CFB not compiled in. Enable with WOLFSSL_AES_CFB\n"); + return 0; +} + +#endif diff --git a/crypto/aes-modes/aes-cfb1.c b/crypto/aes-modes/aes-cfb1.c new file mode 100644 index 00000000..bdfc06c3 --- /dev/null +++ b/crypto/aes-modes/aes-cfb1.c @@ -0,0 +1,315 @@ +/* aes-cfb1.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* AES-CFB1 Example + * This example demonstrates: + * - One-shot encryption using wc_AesCfb1Encrypt() + * - Streaming decryption using wc_AesCfb1Decrypt() in chunks + * Note: CFB1 processes 1 bit at a time, sz parameter is in bits + */ + +#include +#include +#include + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include + +#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB) + +#define AES_KEY_SIZE AES_256_KEY_SIZE + +/* Process 64 bits (8 bytes) at a time for streaming demo */ +#define CHUNK_BITS 64 + +static int read_file(const char* filename, byte** data, word32* dataSz) +{ + FILE* fp; + long fileSz; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("Error: Cannot open file %s\n", filename); + return -1; + } + + fseek(fp, 0, SEEK_END); + fileSz = ftell(fp); + fseek(fp, 0, SEEK_SET); + + *data = (byte*)malloc(fileSz); + if (*data == NULL) { + fclose(fp); + printf("Error: Memory allocation failed\n"); + return -1; + } + + *dataSz = (word32)fread(*data, 1, fileSz, fp); + fclose(fp); + + return 0; +} + +static int write_file(const char* filename, const byte* data, word32 dataSz) +{ + FILE* fp; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + printf("Error: Cannot create file %s\n", filename); + return -1; + } + + fwrite(data, 1, dataSz, fp); + fclose(fp); + + return 0; +} + +/* One-shot encryption */ +static int encrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + WC_RNG rng; + byte iv[AES_BLOCK_SIZE]; + byte* plaintext = NULL; + byte* ciphertext = NULL; + word32 plaintextSz; + word32 plaintextBits; + int ret; + + ret = read_file(inFile, &plaintext, &plaintextSz); + if (ret != 0) return ret; + + plaintextBits = plaintextSz * 8; + + /* IV + ciphertext */ + ciphertext = (byte*)malloc(plaintextSz + AES_BLOCK_SIZE); + if (ciphertext == NULL) { + free(plaintext); + return -1; + } + + /* Generate random IV */ + ret = wc_InitRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); + wc_FreeRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(plaintext); + free(ciphertext); + return ret; + } + + /* One-shot encrypt (sz is in bits for CFB1) */ + ret = wc_AesCfb1Encrypt(&aes, ciphertext + AES_BLOCK_SIZE, plaintext, + plaintextBits); + wc_AesFree(&aes); + + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Prepend IV to output */ + memcpy(ciphertext, iv, AES_BLOCK_SIZE); + + ret = write_file(outFile, ciphertext, plaintextSz + AES_BLOCK_SIZE); + + free(plaintext); + free(ciphertext); + + printf("AES-CFB1 encryption complete (one-shot)\n"); + return ret; +} + +/* Streaming decryption - process in chunks of bits */ +static int decrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + byte iv[AES_BLOCK_SIZE]; + byte* ciphertext = NULL; + byte* plaintext = NULL; + word32 ciphertextSz; + word32 plaintextSz; + word32 totalBits; + word32 offsetBits; + word32 chunkBits; + word32 offsetBytes; + int ret; + + ret = read_file(inFile, &ciphertext, &ciphertextSz); + if (ret != 0) return ret; + + if (ciphertextSz < AES_BLOCK_SIZE) { + free(ciphertext); + printf("Error: File too small\n"); + return -1; + } + + /* Extract IV from beginning */ + memcpy(iv, ciphertext, AES_BLOCK_SIZE); + + plaintextSz = ciphertextSz - AES_BLOCK_SIZE; + totalBits = plaintextSz * 8; + + plaintext = (byte*)malloc(plaintextSz); + if (plaintext == NULL) { + free(ciphertext); + return -1; + } + memset(plaintext, 0, plaintextSz); + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(ciphertext); + free(plaintext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + /* Streaming decrypt - process in chunks of bits */ + printf("AES-CFB1 streaming decryption:\n"); + offsetBits = 0; + while (offsetBits < totalBits) { + chunkBits = totalBits - offsetBits; + if (chunkBits > CHUNK_BITS) { + chunkBits = CHUNK_BITS; + } + + offsetBytes = offsetBits / 8; + + ret = wc_AesCfb1Decrypt(&aes, plaintext + offsetBytes, + ciphertext + AES_BLOCK_SIZE + offsetBytes, + chunkBits); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + printf(" Decrypted chunk: offset=%u bits, size=%u bits\n", + offsetBits, chunkBits); + offsetBits += chunkBits; + } + + wc_AesFree(&aes); + + ret = write_file(outFile, plaintext, plaintextSz); + + free(ciphertext); + free(plaintext); + + printf("AES-CFB1 decryption complete (streaming)\n"); + return ret; +} + +int main(int argc, char** argv) +{ + byte key[AES_KEY_SIZE]; + int ret; + + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + printf("Encrypts input file (one-shot), then decrypts to output file " + "(streaming)\n"); + return 1; + } + + wolfCrypt_Init(); + + /* Use a fixed key for demonstration */ + memset(key, 0x03, AES_KEY_SIZE); + + /* Encrypt to temporary file */ + ret = encrypt_file(argv[1], "temp_encrypted.bin", key, AES_KEY_SIZE); + if (ret != 0) { + printf("Encryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Decrypt to output file */ + ret = decrypt_file("temp_encrypted.bin", argv[2], key, AES_KEY_SIZE); + if (ret != 0) { + printf("Decryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Clean up temp file */ + remove("temp_encrypted.bin"); + + printf("Success! Decrypted file written to %s\n", argv[2]); + + wolfCrypt_Cleanup(); + return 0; +} + +#else + +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + printf("AES-CFB1 not compiled in. Enable with WOLFSSL_AES_CFB\n"); + return 0; +} + +#endif diff --git a/crypto/aes-modes/aes-cfb8.c b/crypto/aes-modes/aes-cfb8.c new file mode 100644 index 00000000..fb8aa888 --- /dev/null +++ b/crypto/aes-modes/aes-cfb8.c @@ -0,0 +1,301 @@ +/* aes-cfb8.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* AES-CFB8 Example + * This example demonstrates: + * - One-shot encryption using wc_AesCfb8Encrypt() + * - Streaming decryption using wc_AesCfb8Decrypt() in chunks + * Note: CFB8 processes 8 bits (1 byte) at a time + */ + +#include +#include +#include + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include + +#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB) + +#define AES_KEY_SIZE AES_256_KEY_SIZE +#define CHUNK_SIZE 8 /* Process 8 bytes at a time for streaming demo */ + +static int read_file(const char* filename, byte** data, word32* dataSz) +{ + FILE* fp; + long fileSz; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("Error: Cannot open file %s\n", filename); + return -1; + } + + fseek(fp, 0, SEEK_END); + fileSz = ftell(fp); + fseek(fp, 0, SEEK_SET); + + *data = (byte*)malloc(fileSz); + if (*data == NULL) { + fclose(fp); + printf("Error: Memory allocation failed\n"); + return -1; + } + + *dataSz = (word32)fread(*data, 1, fileSz, fp); + fclose(fp); + + return 0; +} + +static int write_file(const char* filename, const byte* data, word32 dataSz) +{ + FILE* fp; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + printf("Error: Cannot create file %s\n", filename); + return -1; + } + + fwrite(data, 1, dataSz, fp); + fclose(fp); + + return 0; +} + +/* One-shot encryption */ +static int encrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + WC_RNG rng; + byte iv[AES_BLOCK_SIZE]; + byte* plaintext = NULL; + byte* ciphertext = NULL; + word32 plaintextSz; + int ret; + + ret = read_file(inFile, &plaintext, &plaintextSz); + if (ret != 0) return ret; + + /* IV + ciphertext */ + ciphertext = (byte*)malloc(plaintextSz + AES_BLOCK_SIZE); + if (ciphertext == NULL) { + free(plaintext); + return -1; + } + + /* Generate random IV */ + ret = wc_InitRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); + wc_FreeRng(&rng); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(plaintext); + free(ciphertext); + return ret; + } + + /* One-shot encrypt */ + ret = wc_AesCfb8Encrypt(&aes, ciphertext + AES_BLOCK_SIZE, plaintext, + plaintextSz); + wc_AesFree(&aes); + + if (ret != 0) { + free(plaintext); + free(ciphertext); + return ret; + } + + /* Prepend IV to output */ + memcpy(ciphertext, iv, AES_BLOCK_SIZE); + + ret = write_file(outFile, ciphertext, plaintextSz + AES_BLOCK_SIZE); + + free(plaintext); + free(ciphertext); + + printf("AES-CFB8 encryption complete (one-shot)\n"); + return ret; +} + +/* Streaming decryption - process in chunks */ +static int decrypt_file(const char* inFile, const char* outFile, + const byte* key, word32 keySz) +{ + Aes aes; + byte iv[AES_BLOCK_SIZE]; + byte* ciphertext = NULL; + byte* plaintext = NULL; + word32 ciphertextSz; + word32 plaintextSz; + word32 offset; + word32 chunkSz; + int ret; + + ret = read_file(inFile, &ciphertext, &ciphertextSz); + if (ret != 0) return ret; + + if (ciphertextSz < AES_BLOCK_SIZE) { + free(ciphertext); + printf("Error: File too small\n"); + return -1; + } + + /* Extract IV from beginning */ + memcpy(iv, ciphertext, AES_BLOCK_SIZE); + + plaintextSz = ciphertextSz - AES_BLOCK_SIZE; + plaintext = (byte*)malloc(plaintextSz); + if (plaintext == NULL) { + free(ciphertext); + return -1; + } + + /* Initialize AES */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret != 0) { + free(ciphertext); + free(plaintext); + return ret; + } + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + /* Streaming decrypt - process in chunks */ + printf("AES-CFB8 streaming decryption:\n"); + offset = 0; + while (offset < plaintextSz) { + chunkSz = plaintextSz - offset; + if (chunkSz > CHUNK_SIZE) { + chunkSz = CHUNK_SIZE; + } + + ret = wc_AesCfb8Decrypt(&aes, plaintext + offset, + ciphertext + AES_BLOCK_SIZE + offset, chunkSz); + if (ret != 0) { + wc_AesFree(&aes); + free(ciphertext); + free(plaintext); + return ret; + } + + printf(" Decrypted chunk: offset=%u, size=%u\n", offset, chunkSz); + offset += chunkSz; + } + + wc_AesFree(&aes); + + ret = write_file(outFile, plaintext, plaintextSz); + + free(ciphertext); + free(plaintext); + + printf("AES-CFB8 decryption complete (streaming)\n"); + return ret; +} + +int main(int argc, char** argv) +{ + byte key[AES_KEY_SIZE]; + int ret; + + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + printf("Encrypts input file (one-shot), then decrypts to output file " + "(streaming)\n"); + return 1; + } + + wolfCrypt_Init(); + + /* Use a fixed key for demonstration */ + memset(key, 0x04, AES_KEY_SIZE); + + /* Encrypt to temporary file */ + ret = encrypt_file(argv[1], "temp_encrypted.bin", key, AES_KEY_SIZE); + if (ret != 0) { + printf("Encryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Decrypt to output file */ + ret = decrypt_file("temp_encrypted.bin", argv[2], key, AES_KEY_SIZE); + if (ret != 0) { + printf("Decryption failed: %d\n", ret); + wolfCrypt_Cleanup(); + return 1; + } + + /* Clean up temp file */ + remove("temp_encrypted.bin"); + + printf("Success! Decrypted file written to %s\n", argv[2]); + + wolfCrypt_Cleanup(); + return 0; +} + +#else + +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + printf("AES-CFB8 not compiled in. Enable with WOLFSSL_AES_CFB\n"); + return 0; +} + +#endif