Skip to content

Instantly share code, notes, and snippets.

@rwg
Created March 14, 2015 08:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwg/d9b39167f49adf5b6e12 to your computer and use it in GitHub Desktop.
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
// 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