/* 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); }
int encrypt(char *cipher, const char *message, int length, public_key kp) { /* Its probably overkill, but I implemented PKCS#1v1.5 paging * Encoded message block is of the form: * EMB = 00 || 02 || PS || 00 || D * Where || is concatenation, D is the message, and PS is a string of * (block_size-|D|-3) non-zero, randomly generated bytes * |D| must be less than block_size - 11, which means we have at least 8 * bytes of PS */ int block_count = 0; int prog = length; char mess_block[BLOCK_SIZE]; mpz_t m; mpz_t c; mpz_init(m); mpz_init(c); while(prog > 0) { int i = 0; int d_len = (prog >= (BLOCK_SIZE - 11)) ? BLOCK_SIZE - 11 : prog; int off; /* Construct the header */ mess_block[i++] = 0x00; mess_block[i++] = 0x02; while(i < (BLOCK_SIZE - d_len - 1)) mess_block[i++] = (rand() % (0xFF - 1)) + 1; mess_block[i++] = 0x00; /* Copy in the message */ memcpy(mess_block + i, message + (length - prog), d_len); // Convert bytestream to integer mpz_import(m, BLOCK_SIZE, 1, sizeof(mess_block[0]), 0, 0, mess_block); // Perform encryption on that block block_encrypt(c, m, kp); // Calculate cipher write offset to take into account that we want to // pad with zeros in the front if the number we get back has fewer bits // than BLOCK_SIZE off = block_count * BLOCK_SIZE; // Base offset to start of this block off += (BLOCK_SIZE - (mpz_sizeinbase(c, 2) + 8 - 1)/8); // See manual for mpz_export // Pull out bytestream of ciphertext mpz_export(cipher + off, NULL, 1, sizeof(char), 0, 0, c); block_count++; prog -= d_len; } mpz_clear(m); mpz_clear(c); return block_count * BLOCK_SIZE; }
int main (int argc, char **argv) { if (argc < 3) { printf("Invalid number of arguments: <key> [-e | -d] <input>\n"); exit(1); } int mode = (strcmp("-d", argv[2]) == 0) ? DECRYPT : ENCRYPT; unsigned char *input; int input_size = hex_decode(argv[3], &input); unsigned char *key; int key_size = hex_decode(argv[1], &key); printf("mode: %s\n", mode == DECRYPT ? "decrypt" : "encrypt"); block_state *block = malloc(sizeof(block_state)); if (block) memset(block, 0, sizeof(block_state)); unsigned char *e_buffer = malloc(input_size); unsigned char *d_buffer = malloc(input_size); block_init(block, key, key_size); block_encrypt(block, input, e_buffer); block_decrypt(block, e_buffer, d_buffer); printf("input buffer:\n"); print_buffer(input, input_size); printf("encrypted buffer:\n"); print_buffer(e_buffer, input_size); printf("decrypted buffer:\n"); print_buffer(d_buffer, input_size); printf("\n"); free(e_buffer); free(d_buffer); free(block); free(input); free(key); }
int main() { int i; mpz_t M; mpz_init(M); mpz_t C; mpz_init(C); mpz_t DC; mpz_init(DC); private_key ku; public_key kp; // Initialize public key mpz_init(kp.n); mpz_init(kp.e); // Initialize private key mpz_init(ku.n); mpz_init(ku.e); mpz_init(ku.d); mpz_init(ku.p); mpz_init(ku.q); generate_keys(&ku, &kp); printf("---------------Private Key-----------------"); printf("kp.n is [%s]\n", mpz_get_str(NULL, 16, kp.n)); printf("kp.e is [%s]\n", mpz_get_str(NULL, 16, kp.e)); printf("---------------Public Key------------------"); printf("ku.n is [%s]\n", mpz_get_str(NULL, 16, ku.n)); printf("ku.e is [%s]\n", mpz_get_str(NULL, 16, ku.e)); printf("ku.d is [%s]\n", mpz_get_str(NULL, 16, ku.d)); printf("ku.p is [%s]\n", mpz_get_str(NULL, 16, ku.p)); printf("ku.q is [%s]\n", mpz_get_str(NULL, 16, ku.q)); char buf[6*BLOCK_SIZE]; for(i = 0; i < 6*BLOCK_SIZE; i++) buf[i] = rand() % 0xFF; mpz_import(M, (6*BLOCK_SIZE), 1, sizeof(buf[0]), 0, 0, buf); printf("original is [%s]\n", mpz_get_str(NULL, 16, M)); block_encrypt(C, M, kp); printf("encrypted is [%s]\n", mpz_get_str(NULL, 16, C)); block_decrypt(DC, C, ku); printf("decrypted is [%s]\n", mpz_get_str(NULL, 16, DC)); return 0; }
static int decrypt(lua_State* pState) { AESObject* aes = (AESObject*)lua_touserdata(pState, 1); unsigned char *buffer, *str; unsigned char temp[BLOCK_SIZE]; int i, j, len; str = lua_tolstring(pState, 2, &len); if (len == 0) { lua_pushstring(pState, ""); return 1; } if ( (len % BLOCK_SIZE) !=0 && (aes->mode!=MODE_CFB)) { luaL_error(pState, "Input strings must be " "a multiple of %d in length", BLOCK_SIZE); return 0; } if (aes->mode == MODE_CFB && (len % (aes->segment_size/8) !=0)) { luaL_error(pState, "aInput strings must be a multiple of " "the segment size %d in length", aes->segment_size/8); return 0; } buffer = (char*)malloc(len); if (!buffer) { luaL_error(pState, "alloc memory error"); return 0; } switch(aes->mode) { case(MODE_ECB): for(i=0; i<len; i+=BLOCK_SIZE) { block_decrypt(&(aes->st), str+i, buffer+i); } break; case(MODE_CBC): for(i=0; i<len; i+=BLOCK_SIZE) { memcpy(aes->oldCipher, aes->IV, BLOCK_SIZE); block_decrypt(&(aes->st), str+i, temp); for(j=0; j<BLOCK_SIZE; j++) { buffer[i+j]=temp[j]^aes->IV[j]; aes->IV[j]=str[i+j]; } } break; case(MODE_CFB): for(i=0; i<len; i+=aes->segment_size/8) { block_encrypt(&(aes->st), aes->IV, temp); for (j=0; j<aes->segment_size/8; j++) { buffer[i+j] = str[i+j]^temp[j]; } if (aes->segment_size == BLOCK_SIZE * 8) { /* s == b: segment size is identical to the algorithm block size */ memcpy(aes->IV, str + i, BLOCK_SIZE); } else if ((aes->segment_size % 8) == 0) { int sz = aes->segment_size/8; memmove(aes->IV, aes->IV + sz, BLOCK_SIZE-sz); memcpy(aes->IV + BLOCK_SIZE - sz, str + i, sz); } else { /* segment_size is not a multiple of 8; currently this can't happen */ } } break; case (MODE_OFB): for(i=0; i<len; i+=BLOCK_SIZE) { block_encrypt(&(aes->st), aes->IV, temp); memcpy(aes->IV, temp, BLOCK_SIZE); for(j=0; j<BLOCK_SIZE; j++) { buffer[i+j] = str[i+j] ^ aes->IV[j]; } } break; default: free(buffer); luaL_error(pState, "not support mode"); return 0; } lua_pushlstring(pState, buffer, len); free(buffer); return 1; }