Created
March 14, 2015 08:01
-
-
Save rwg/d9b39167f49adf5b6e12 to your computer and use it in GitHub Desktop.
Demonstration program for CRYPTO_128_unwrap() bug fixed by https://github.com/openssl/openssl/pull/179
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Test program demonstrating CRYPTO_128_unwrap() bug. | |
// See also: https://github.com/openssl/openssl/pull/179 | |
// | |
// Compile with: | |
// cc -std=c99 -o key-wrap-bug \ | |
// -I/path/to/openssl/include -L/path/to/openssl/lib -lcrypto \ | |
// key-wrap-bug.c | |
#include <ctype.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <openssl/aes.h> | |
#include <openssl/modes.h> | |
void xxd(unsigned char *b, size_t b_len) { | |
for (unsigned char *p = b; p < b + b_len; p += 16) { | |
printf("%07lx: ", p - b); | |
for (unsigned char *q = p; q < p + 16; q++) { | |
if (q < b + b_len) { | |
printf("%02X ", *q); | |
} else { | |
printf(" "); | |
} | |
} | |
printf(" "); | |
for (unsigned char *q = p; q < p + 16 && q < b + b_len; q++) { | |
printf("%c", isprint(*q) ? *q : '.'); | |
} | |
printf("\n"); | |
} | |
printf("\n"); | |
} | |
int main(void) { | |
char *material = "HEREStheMATERIAL"; | |
char *key = "0123456789abcdef"; | |
char *badkey = "thisKEYisGARBAGE"; | |
AES_KEY aesenckey, aesdeckey, badaesdeckey; | |
unsigned char wrapped[256], unwrapped[256]; | |
size_t wrapped_len, unwrapped_len; | |
int r; | |
printf("*** This is what we're going to wrap...\n\n"); | |
printf("material =\n"); | |
xxd((unsigned char *)material, 16); | |
printf("*** This is the key we're going to use...\n\n"); | |
printf("key =\n"); | |
xxd((unsigned char *)key, 16); | |
printf("*** This is a garbage key that shows the bug...\n\n"); | |
printf("badkey =\n"); | |
xxd((unsigned char *)badkey, 16); | |
printf("*** Initialize our AES_KEY structures...\n\n"); | |
r = AES_set_encrypt_key((unsigned char *)key, 128, &aesenckey); | |
printf("AES_set_encrypt_key(key, 128, &aesenckey) returned %d\n\n", r); | |
r = AES_set_decrypt_key((unsigned char *)key, 128, &aesdeckey); | |
printf("AES_set_decrypt_key(key, 128, &aesdeckey) returned %d\n\n", r); | |
r = AES_set_decrypt_key((unsigned char *)badkey, 128, &badaesdeckey); | |
printf("AES_set_decrypt_key(badkey, 128, &badaesdeckey) returned %d\n\n", r); | |
printf("*** Okay, here we wrap the material with the key. This works fine.\n\n"); | |
wrapped_len = CRYPTO_128_wrap(&aesenckey, NULL, wrapped, (unsigned char *)material, 16, (block128_f)&AES_encrypt); | |
printf("CRYPTO_128_wrap(&aesenckey, NULL, wrapped, material, 16, &AES_encrypt) returned %lu\n\n", wrapped_len); | |
if (wrapped_len <= 0) { | |
exit(1); | |
} | |
printf("wrapped =\n"); | |
xxd(wrapped, wrapped_len); | |
printf("*** Now we unwrap what we just wrapped. This also works fine.\n\n"); | |
unwrapped_len = CRYPTO_128_unwrap(&aesdeckey, NULL, unwrapped, wrapped, wrapped_len, (block128_f)&AES_decrypt); | |
printf("CRYPTO_128_unwrap(&aesdeckey, NULL, unwrapped, wrapped, wrapped_len, &AES_decrypt) returned %lu\n\n", unwrapped_len); | |
if (unwrapped_len <= 0) { | |
exit(1); | |
} | |
printf("unwrapped =\n"); | |
xxd(unwrapped, unwrapped_len); | |
printf("*** Now we unwrap it again with an incorrect key.\n"); | |
printf("*** But CRYPTO_128_unwrap() acts like everything\n"); | |
printf("*** is fine, even though it's returning garbage!\n\n"); | |
unwrapped_len = CRYPTO_128_unwrap(&badaesdeckey, NULL, unwrapped, wrapped, wrapped_len, (block128_f)&AES_decrypt); | |
printf("CRYPTO_128_unwrap(&badaesdeckey, NULL, unwrapped, wrapped, wrapped_len, &AES_decrypt) returned %lu\n\n", unwrapped_len); | |
if (unwrapped_len <= 0) { | |
exit(1); | |
} | |
printf("unwrapped =\n"); | |
xxd(unwrapped, unwrapped_len); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment