/* Take a chunk of data, encrypt it in the same way OpenSSL would * (with a default of AES in CBC mode). */ size_t rij_encrypt(unsigned char *in, size_t in_len, const char *key, const int key_len, unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val; unsigned char *ondx = out; rijndael_init(&ctx, key, key_len, NULL, encryption_mode); /* Prepend the salt to the ciphertext... */ memcpy(ondx, "Salted__", SALT_LEN); ondx+=SALT_LEN; memcpy(ondx, ctx.salt, SALT_LEN); ondx+=SALT_LEN; /* Add padding to the original plaintext to ensure that it is a * multiple of the Rijndael block size */ pad_val = RIJNDAEL_BLOCKSIZE - (in_len % RIJNDAEL_BLOCKSIZE); for (i = (int)in_len; i < ((int)in_len+pad_val); i++) in[i] = pad_val; block_encrypt(&ctx, in, in_len+pad_val, ondx, ctx.iv); ondx += in_len+pad_val; zero_buf((char *)ctx.key, RIJNDAEL_MAX_KEYSIZE); zero_buf((char *)ctx.iv, RIJNDAEL_BLOCKSIZE); zero_buf((char *)ctx.salt, SALT_LEN); return(ondx - out); }
/* Decrypt the given data. */ size_t rij_decrypt(unsigned char *in, size_t in_len, const char *key, const int key_len, unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val, pad_err = 0; unsigned char *pad_s; unsigned char *ondx = out; if(in == NULL || key == NULL || out == NULL) return 0; rijndael_init(&ctx, key, key_len, in, encryption_mode); /* Remove the first block since it contains the salt (it was consumed * by the rijndael_init() function above). */ in_len -= RIJNDAEL_BLOCKSIZE; memmove(in, in+RIJNDAEL_BLOCKSIZE, in_len); block_decrypt(&ctx, in, in_len, out, ctx.iv); ondx += in_len; /* Find and remove padding. */ pad_val = *(ondx-1); if(pad_val >= 0 && pad_val <= RIJNDAEL_BLOCKSIZE) { pad_s = ondx - pad_val; for(i=0; i < (ondx-pad_s); i++) { if(*(pad_s+i) != pad_val) pad_err++; } if(pad_err == 0) ondx -= pad_val; } *ondx = '\0'; zero_buf((char *)ctx.key, RIJNDAEL_MAX_KEYSIZE); zero_buf((char *)ctx.iv, RIJNDAEL_BLOCKSIZE); zero_buf((char *)ctx.salt, SALT_LEN); return(ondx - out); }