blob: f13d30ff0cf2786601f203dadd830903cb46579a [file] [log] [blame]
/**
* @file test_gcm_decrypt.c
* @author Kealan McCusker
* @brief Test function for Galois Counter Mode decryption,
*
* LICENSE
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* Build executible after installation:
gcc -std=c99 -g ./test_gcm_decrypt.c -I/opt/amcl/include -L/opt/amcl/lib -lamcl -o test_gcm_decrypt
*/
#include "arch.h"
#include "amcl.h"
#include "utils.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINE_LEN 300
// #define DEBUG
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("usage: ./test_gcm_decrypt [path to test vector file]\n");
exit(EXIT_FAILURE);
}
FILE * fp = NULL;
char line[LINE_LEN];
char * linePtr = NULL;
int l1=0;
char * Key = NULL;
int KeyLen = 0;
const char* KeyStr = "Key = ";
char * IV = NULL;
int IVLen = 0;
const char* IVStr = "IV = ";
char * PT = NULL;
const char* PTStr = "PT = ";
char * PT1 = NULL;
octet PT1Oct;
char * AAD = NULL;
int AADLen = 0;
const char* AADStr = "AAD = ";
char * CT = NULL;
int CTLen = 0;
const char* CTStr = "CT = ";
char Tag[16];
const char* TagStr = "Tag = ";
char * Tag1 = NULL;
octet Tag1Oct;
int TagLen=0;
const char* FAILStr = "FAIL";
fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("ERROR opening test vector file\n");
exit(EXIT_FAILURE);
}
bool readLine = false;
int i=0;
while (fgets(line, LINE_LEN, fp) != NULL)
{
i++;
readLine = true;
if (!strncmp(line, KeyStr, strlen(KeyStr)))
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
// Find hex value in string
linePtr = line + strlen(KeyStr);
// Allocate memory
l1 = strlen(linePtr)-1;
KeyLen = l1/2;
Key = (char*) malloc (KeyLen);
if (Key==NULL)
exit(EXIT_FAILURE);
// Key binary value
amcl_hex2bin(linePtr, Key, l1);
}
if (!strncmp(line, IVStr, strlen(IVStr)))
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
// Find hex value in string
linePtr = line + strlen(IVStr);
// Allocate memory
l1 = strlen(linePtr)-1;
IVLen = l1/2;
IV = (char*) malloc (IVLen);
if (IV==NULL)
exit(EXIT_FAILURE);
// IV binary value
amcl_hex2bin(linePtr, IV, l1);
}
if (!strncmp(line, CTStr, strlen(CTStr)))
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
// Find hex value in string
linePtr = line + strlen(CTStr);
// Allocate memory
l1 = strlen(linePtr);
CTLen = l1/2;
CT = (char*) malloc (CTLen);
if (CT==NULL)
exit(EXIT_FAILURE);
PT = (char*) malloc (CTLen);
if (PT==NULL)
exit(EXIT_FAILURE);
// CT binary value
amcl_hex2bin(linePtr, CT, l1);
}
if (!strncmp(line, AADStr, strlen(AADStr)))
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
// Find hex value in string
linePtr = line + strlen(AADStr);
// Allocate memory
l1 = strlen(linePtr)-1;
AADLen = l1/2;
AAD = (char*) malloc (AADLen);
if (AAD==NULL)
exit(EXIT_FAILURE);
// AAD binary value
amcl_hex2bin(linePtr, AAD, l1);
}
if (!strncmp(line, TagStr, strlen(TagStr)))
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
// Find hex value in string
linePtr = line + strlen(TagStr);
// Allocate memory
l1 = strlen(linePtr);
TagLen = l1/2;
Tag1 = (char*) malloc (TagLen);
if (Tag1==NULL)
exit(EXIT_FAILURE);
// Golden Tag value
amcl_hex2bin(linePtr, Tag1, l1);
Tag1Oct.len=TagLen;
Tag1Oct.max=TagLen;
Tag1Oct.val=Tag1;
}
if ( !strncmp(line, PTStr, strlen(PTStr)) || !strncmp(line, FAILStr, strlen(FAILStr)) )
{
#ifdef DEBUG
printf("line %d %s\n", i,line);
#endif
if (!strncmp(line, PTStr, strlen(PTStr)))
{
// Find hex value in string
linePtr = line + strlen(PTStr);
// Allocate memory
l1 = strlen(linePtr)-1;
PT1 = (char*) malloc (CTLen);
if (PT1==NULL)
exit(EXIT_FAILURE);
// Golden PT value
amcl_hex2bin(linePtr, PT1, l1);
PT1Oct.len=CTLen;
PT1Oct.max=CTLen;
PT1Oct.val=PT1;
}
gcm g;
GCM_init(&g,KeyLen,Key,IVLen,IV);
GCM_add_header(&g,AAD,AADLen);
GCM_add_cipher(&g,PT,CT,CTLen);
GCM_finish(&g,Tag);
octet PTOct = {CTLen,CTLen, PT};
octet TagOct = {TagLen,TagLen, Tag};
int rc;
if (!strncmp(line, PTStr, strlen(PTStr)))
{
rc = OCT_comp(&PT1Oct,&PTOct);
if (!rc)
{
printf("TEST GCM DECRYPT FAILED COMPARE PT LINE %d\n",i);
exit(EXIT_FAILURE);
}
}
if (!strncmp(line, PTStr, strlen(PTStr)))
{
rc = OCT_comp(&Tag1Oct,&TagOct);
if (!rc)
{
printf("TEST GCM DECRYPT FAILED COMPARE Tag LINE %d\n",i);
exit(EXIT_FAILURE);
}
}
// Expect tag to be different from input tag
if (!strncmp(line, FAILStr, strlen(FAILStr)))
{
rc = OCT_comp(&Tag1Oct,&TagOct);
if (rc)
{
printf("TEST GCM DECRYPT FAILED COMPARE Tag LINE %d\n",i);
exit(EXIT_FAILURE);
}
}
free(Key);
Key = NULL;
free(IV);
IV = NULL;
free(PT);
PT = NULL;
free(AAD);
AAD = NULL;
free(CT);
CT = NULL;
free(PT1);
PT1 = NULL;
free(Tag1);
Tag1 = NULL;
}
}
fclose(fp);
if (!readLine)
{
printf("ERROR Empty test vector file\n");
exit(EXIT_FAILURE);
}
printf("SUCCESS TEST AES-GCM DECRYPT PASSED\n");
exit(EXIT_SUCCESS);
}