I am trying include different IPSec algorithms in C++ based application program. In that I wanted to use AES-XCBC algorithm described here: http://www.faqs.org/rfcs/rfc3566.html
I looked at OpenSSL's API's but did not find suitable ones for AES-XCBC like one for AES_GCM described in OpenSSL's wiki: https://www.openssl.org/docs/man1.1.0/man3/EVP_EncryptInit_ex.html
But was able to find this test program from OpenSwan library: https://github.com/xelerance/Openswan/blob/6055fc6fa444f3d5b89ad0f7d3ec277eedaa9282/lib/libcrypto/libaes/test_main_mac.c
I modified the program to use 2nd test vector from algorithm description link in RFC 3566 like:
Key (K) : 000102030405060708090a0b0c0d0e0f
Message (M) : 000102
AES-XCBC-MAC : 5b376580ae2f19afe7219ceef172756f
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "aes.h"
#include "aes_xcbc_mac.h"
#define STR "Hola guasssso c|mo estais ...012"
void print_hash(const u_int8_t *hash) {
printf("%08x %08x %08x %08x\n",
*(u_int32_t*)(&hash[0]),
*(u_int32_t*)(&hash[4]),
*(u_int32_t*)(&hash[8]),
*(u_int32_t*)(&hash[12]));
}
int main(int argc, char *argv[]) {
aes_block key= { 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f };
u_int8_t hash[16];
unsigned char str[3] = {0x00, 0x01, 0x02};
aes_context_mac ctx;
AES_xcbc_mac_set_key(&ctx, (u_int8_t *)&key, sizeof(key));
AES_xcbc_mac_hash(&ctx, (u_int8_t *) &str, sizeof(str), hash);
print_has(hash);
str[2]='x';
AES_xcbc_mac_hash(&ctx,(u_int8_t *) &str, sizeof(str), hash);
print_hash(hash);
return 0;
}
The output that is printed for the above input is:
b176b661 d551b66f 64889d60 18e71c76
This is different from expected mac from RFC 3566. Am I correctly using the API? Is there any reference implementation for this algorithm?
Another library libtomcrypt does have implementation of AES_XCBC. The program can be modified to use xcbc_memory function form libtomcrypt and it's test program.
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <tomcrypt.h>
#define STR "Hola guasssso c|mo estais ...012"
void print_hash(const u_int8_t *hash) {
printf("%08x %08x %08x %08x\n",
*(u_int32_t*)(&hash[0]),
*(u_int32_t*)(&hash[4]),
*(u_int32_t*)(&hash[8]),
*(u_int32_t*)(&hash[12]));
}
int main(int argc, char *argv[]) {
uint8_t key[16]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t hash[16];
int idx,err;
unsigned char str[3] = {0x00, 0x01, 0x02};
unsigned long taglen = 16;
register_cipher( & aes_desc);
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
printf("idx:%d\n",idx);
return CRYPT_NOP;
}
}
if ((err = xcbc_memory(idx, key, 16, str, 3,hash, &taglen)) != CRYPT_OK) {
printf("err:%d\n",idx);
return err;
}
print_has(hash);
str[2]='x';
if ((err = xcbc_memory(idx, key, 16, str, 3,hash, &taglen)) != CRYPT_OK) {
printf("err:%d\n",idx);
return err;
}
print_hash(hash);
return 0;
}