Untitled
#include <stdint.h> #include <stdlib.h> #include <string.h> #include <time.h> // Blowfish functions (assuming these are correctly implemented elsewhere) void blowfish_keyschedule(const uint8_t *key, size_t keylen, uint32_t *ctx, uint8_t *table); void blowfish_encrypt_block(const uint32_t *ctx, const uint8_t *table, const uint8_t *plaintext, uint8_t *ciphertext); #define BLOWFISH_BLOCK_SIZE 8 // Revised encryption function uint8_t* blowfish_cbc_encrypt( const uint8_t *plaintext, size_t inlen, const uint8_t *key, size_t keylen, size_t *outlen ) { // Validate inputs if (!plaintext || !key || keylen < 4 || keylen > 56) { return NULL; } // Allocate context and table uint32_t ctx[18]; uint8_t table[4*256]; blowfish_keyschedule(key, keylen, ctx, table); // Generate random IV (Critical security fix!) uint8_t iv[BLOWFISH_BLOCK_SIZE]; arc4random_buf(iv, BLOWFISH_BLOCK_SIZE); // Use secure random generator // Add PKCS#7 padding (Security & correctness fix) size_t padded_len = inlen + (BLOWFISH_BLOCK_SIZE - (inlen % BLOWFISH_BLOCK_SIZE)); uint8_t *padded_data = malloc(padded_len); memcpy(padded_data, plaintext, inlen); memset(padded_data + inlen, (padded_len - inlen), padded_len - inlen); // Allocate output buffer (IV + ciphertext) *outlen = BLOWFISH_BLOCK_SIZE + padded_len; uint8_t *ciphertext = malloc(*outlen); memcpy(ciphertext, iv, BLOWFISH_BLOCK_SIZE); // Prepend IV // CBC mode encryption uint8_t previous_block[BLOWFISH_BLOCK_SIZE]; memcpy(previous_block, iv, BLOWFISH_BLOCK_SIZE); for (size_t i = 0; i < padded_len; i += BLOWFISH_BLOCK_SIZE) { // XOR with previous ciphertext block for (int j = 0; j < BLOWFISH_BLOCK_SIZE; j++) { padded_data[i+j] ^= previous_block[j]; } // Encrypt block blowfish_encrypt_block(ctx, table, &padded_data[i], &ciphertext[BLOWFISH_BLOCK_SIZE + i]); // Update previous block memcpy(previous_block, &ciphertext[BLOWFISH_BLOCK_SIZE + i], BLOWFISH_BLOCK_SIZE); } free(padded_data); return ciphertext; }
Leave a Comment