void edit(char *encrypted, size_t len, size_t offset, char *new_text) { size_t n = strlen(new_text); assert(offset + n <= len); ctr_crypt(encrypted, encrypted, len, nonce, key); memcpy(encrypted + offset, new_text, n); ctr_crypt(encrypted, encrypted, len, nonce, key); }
static void test_uncipher_ctr ( const struct nettle_cipher *cipher, const uint8_t * key, unsigned key_length, const uint8_t * cipheredtext, unsigned length, const uint8_t * cleartext, const uint8_t * ictr) { void *ctx = malloc (cipher->context_size); uint8_t *data = malloc (length); uint8_t *ctr = malloc (cipher->block_size); cipher->set_encrypt_key (ctx, key_length, key); memcpy (ctr, ictr, cipher->block_size); ctr_crypt (ctx, cipher->encrypt, cipher->block_size, ctr, length, data, cipheredtext); if (compare_buffer (data, length, cleartext, length) != 0) { fail ("Fail: test_uncipher_ctr\n"); } free (ctx); free (data); free (ctr); }
int main() { srand(44); init_keys(); char *doc = calloc(1, 1); size_t doc_len = 0; char *line = NULL; size_t n = 0; while (getline(&line, &n, stdin) != -1) { size_t line_len = strlen(line); doc = realloc(doc, doc_len + line_len); strncpy(doc + doc_len, line, line_len - 1); doc_len += line_len - 1; doc[doc_len] = '\0'; } size_t num_bytes = num_bytes_from_base64(doc_len); char *as_bytes = calloc(num_bytes + 1, 1); num_bytes = base64_to_bytes(doc, as_bytes, num_bytes); char *decrypted = calloc(num_bytes + 1, 1); char *encrypted = calloc(num_bytes + 1, 1); aes_decrypt(as_bytes, decrypted, num_bytes, "YELLOW SUBMARINE"); ctr_crypt(decrypted, encrypted, num_bytes, nonce, key); // E = C = P ^ K char *a = calloc(num_bytes + 1, 1); memset(a, 'a', num_bytes); memcpy(decrypted, encrypted, num_bytes); edit(encrypted, num_bytes, 0, a); // D = A ^ K; xor(decrypted, encrypted, num_bytes, decrypted); // D = (A ^ K) ^ (P ^ K) = A ^ P xor(decrypted, a, num_bytes, decrypted); // D = (A ^ P) ^ A = P printf("%s\n", decrypted); free(doc); free(as_bytes); free(encrypted); free(decrypted); free(a); }
void test_cipher_ctr(const struct nettle_cipher *cipher, const struct tstring *key, const struct tstring *cleartext, const struct tstring *ciphertext, const struct tstring *ictr) { void *ctx = xalloc(cipher->context_size); uint8_t *data; uint8_t *ctr = xalloc(cipher->block_size); uint8_t *octr = xalloc(cipher->block_size); unsigned length; unsigned low, nblocks; ASSERT (cleartext->length == ciphertext->length); length = cleartext->length; ASSERT (ictr->length == cipher->block_size); /* Compute expected counter value after the operation. */ nblocks = (length + cipher->block_size - 1) / cipher->block_size; ASSERT (nblocks < 0x100); memcpy (octr, ictr->data, cipher->block_size - 1); low = ictr->data[cipher->block_size - 1] + nblocks; octr[cipher->block_size - 1] = low; if (low >= 0x100) INCREMENT (cipher->block_size - 1, octr); data = xalloc(length); cipher->set_encrypt_key(ctx, key->length, key->data); memcpy(ctr, ictr->data, cipher->block_size); ctr_crypt(ctx, cipher->encrypt, cipher->block_size, ctr, length, data, cleartext->data); if (!MEMEQ(length, data, ciphertext->data)) { fprintf(stderr, "CTR encrypt failed:\nInput:"); tstring_print_hex(cleartext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); tstring_print_hex(ciphertext); fprintf(stderr, "\n"); FAIL(); } ASSERT (MEMEQ (cipher->block_size, ctr, octr)); memcpy(ctr, ictr->data, cipher->block_size); ctr_crypt(ctx, cipher->encrypt, cipher->block_size, ctr, length, data, data); if (!MEMEQ(length, data, cleartext->data)) { fprintf(stderr, "CTR decrypt failed:\nInput:"); tstring_print_hex(ciphertext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); tstring_print_hex(cleartext); fprintf(stderr, "\n"); FAIL(); } ASSERT (MEMEQ (cipher->block_size, ctr, octr)); free(ctx); free(data); free(octr); free(ctr); }