aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorareviu <areviu.info@gmail.com>2018-03-25 09:16:57 +0000
committerareviu <areviu.info@gmail.com>2018-03-25 09:16:57 +0000
commitc44880635c6c6f8b7b026c79ae5ec1e49e38541c (patch)
treeb66a5c2903e3123642b5f20804beb15ff13a7939
parent1d3bbc72c326e87bb688cbce39ea93b71b4406d3 (diff)
downloadChibiOS-c44880635c6c6f8b7b026c79ae5ec1e49e38541c.tar.gz
ChibiOS-c44880635c6c6f8b7b026c79ae5ec1e49e38541c.tar.bz2
ChibiOS-c44880635c6c6f8b7b026c79ae5ec1e49e38541c.zip
added gcm for sama crypto
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11851 110e8d01-0319-4d1e-a829-52ad28d1bb01
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk3
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h1
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c215
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h25
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c91
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h17
-rw-r--r--test/crypto/configuration.xml357
-rw-r--r--test/crypto/crypto_test.mk4
-rw-r--r--test/crypto/source/test/cry_test_root.c3
-rw-r--r--test/crypto/source/test/cry_test_root.h11
-rw-r--r--test/crypto/source/test/cry_test_sequence_008.c357
-rw-r--r--test/crypto/source/test/cry_test_sequence_008.h27
-rw-r--r--test/crypto/source/testref/ref_gcm.c77
-rw-r--r--test/crypto/source/testref/ref_gcm.h82
14 files changed, 1239 insertions, 31 deletions
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
index 9673bb649..24fcc73b3 100644
--- a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
@@ -1,7 +1,8 @@
PLATFORMSRC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c \
$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c \
$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c \
- $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c
+ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c \
+ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
index 029a209ac..b90535392 100644
--- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
@@ -62,6 +62,7 @@ extern void samaCryptoDriverDisable(CRYDriver *cryp);
#include "sama_aes_lld.h"
#include "sama_tdes_lld.h"
#include "sama_sha_lld.h"
+#include "sama_gcm_lld.h"
#endif /* HAL_USE_CRY */
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c
new file mode 100644
index 000000000..2496c03d3
--- /dev/null
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c
@@ -0,0 +1,215 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed 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.
+ */
+#include "hal.h"
+#include <string.h>
+#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
+
+#include "sama_crypto_lld.h"
+
+static void incr32(uint8_t* j0)
+{
+
+ uint32_t counter = j0[15] | j0[14] << 0x8 | j0[13] << 0x10 | j0[12] << 0x18;
+
+ counter++;
+
+ j0[12] = (counter>>24) & 0xFF;
+ j0[13] = (counter>>16) & 0xFF;
+ j0[14] = (counter>>8) & 0xFF;
+ j0[15] = counter & 0xFF;
+}
+
+static cryerror_t sama_gcm_lld_process_dma(CRYDriver *cryp,cgmcontext * cxt)
+{
+#if defined(SAMA_DMA_REQUIRED)
+
+ osalDbgAssert(cryp->thread == NULL, "already waiting");
+
+
+ //set chunk size
+ cryp->dmachunksize = DMA_CHUNK_SIZE_4;
+
+ if ((cryp->config->cfbs != AES_CFBS_128))
+ cryp->dmachunksize = DMA_CHUNK_SIZE_1;
+
+ //set dma width
+ cryp->dmawith = DMA_DATA_WIDTH_WORD;
+
+ if (cryp->config->cfbs == AES_CFBS_16)
+ cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD;
+ if (cryp->config->cfbs == AES_CFBS_8)
+ cryp->dmawith = DMA_DATA_WIDTH_BYTE;
+
+ cryp->rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
+ XDMAC_CC_PROT_SEC |
+ XDMAC_CC_MBSIZE_SINGLE |
+ XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE(cryp->dmachunksize) |
+ XDMAC_CC_DWIDTH(cryp->dmawith) |
+ XDMAC_CC_SIF_AHB_IF1 |
+ XDMAC_CC_DIF_AHB_IF0 |
+ XDMAC_CC_SAM_FIXED_AM |
+ XDMAC_CC_DAM_INCREMENTED_AM |
+ XDMAC_CC_PERID(PERID_AES_RX);
+
+ cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN |
+ XDMAC_CC_PROT_SEC |
+ XDMAC_CC_MBSIZE_SINGLE |
+ XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) |
+ XDMAC_CC_DWIDTH(cryp->dmawith) |
+ XDMAC_CC_SIF_AHB_IF0 |
+ XDMAC_CC_DIF_AHB_IF1 |
+ XDMAC_CC_SAM_INCREMENTED_AM |
+ XDMAC_CC_DAM_FIXED_AM |
+ XDMAC_CC_PERID(PERID_AES_TX);
+
+ dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode);
+ dmaChannelSetMode(cryp->dmatx, cryp->txdmamode);
+
+ // Writing channel
+ dmaChannelSetSource(cryp->dmatx, cxt->in);
+ dmaChannelSetDestination(cryp->dmatx, AES->AES_IDATAR);
+ dmaChannelSetTransactionSize(cryp->dmatx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith)));
+
+
+ // Reading channel
+ dmaChannelSetSource(cryp->dmarx, AES->AES_ODATAR);
+ dmaChannelSetDestination(cryp->dmarx, cxt->out);
+ dmaChannelSetTransactionSize(cryp->dmarx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith)));
+
+ AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_IDATAR0_START)))
+ | AES_MR_CKEY_PASSWD);
+
+ //Enable aes interrupt
+ AES->AES_IER = AES_IER_DATRDY;
+
+ osalSysLock();
+
+ dmaChannelEnable(cryp->dmarx);
+ dmaChannelEnable(cryp->dmatx);
+
+ osalThreadSuspendS(&cryp->thread);
+
+ osalSysUnlock();
+
+
+#endif //#if defined(SAMA_DMA_REQUIRED)
+ return CRY_NOERROR;
+
+}
+
+cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt)
+{
+ cryerror_t ret;
+ uint32_t *ref32;
+ uint8_t i;
+ uint8_t J0[16] = { 0x00 };
+
+
+ osalMutexLock(&cryp->mutex);
+
+
+ //AES soft reset
+ AES->AES_CR = AES_CR_SWRST;
+
+ //AES set op mode
+ AES->AES_MR =((AES_MR_OPMOD_Msk & (AES_MR_OPMOD_GCM)) | AES_MR_GTAGEN | AES_MR_CKEY_PASSWD);
+
+
+ //AES set key size
+ ret = sama_aes_lld_set_key_size(cryp->key0_size);
+
+
+ if (ret == CRY_NOERROR) {
+
+ AES->AES_MR |= ( ((AES_MR_SMOD_Msk & (AES_MR_SMOD_MANUAL_START))) | AES_MR_CKEY_PASSWD);
+
+ sama_aes_lld_write_key(cryp->key0_buffer,NULL, cryp->key0_size);
+
+ AES->AES_CR = AES_CR_START;
+
+ while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY);
+
+ //J0
+
+ memcpy(J0, cxt->params.iv, 16); // copy the IV to the first 12 bytes of J0
+
+ incr32(J0);
+
+ // Write incr32(J0) into IV.
+
+ ref32 = (uint32_t*)J0;
+ AES->AES_IVR[0] = ref32[0];
+ AES->AES_IVR[1] = ref32[1];
+ AES->AES_IVR[2] = ref32[2];
+ AES->AES_IVR[3] = ref32[3];
+
+
+ AES->AES_AADLENR = cxt->aadsize;
+ AES->AES_CLENR = cxt->c_size;
+
+ if (cxt->params.encrypt)
+ AES->AES_MR |= AES_MR_CIPHER;
+ else
+ AES->AES_MR &= ~AES_MR_CIPHER;
+
+ AES->AES_MR |= AES_MR_GTAGEN| AES_MR_CKEY_PASSWD;
+
+
+ for (i = 0; i < cxt->aadsize; i += cxt->params.block_size) {
+
+ sama_aes_lld_set_input((uint32_t *) ((cxt->aad) + i));
+
+ AES->AES_CR = AES_CR_START;
+
+ while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY);
+
+ }
+
+ if (cryp->config->transfer_mode == TRANSFER_POLLING) {
+ for (i = 0; i < cxt->c_size; i += cxt->params.block_size) {
+
+ sama_aes_lld_set_input((uint32_t *) ((cxt->in) + i));
+
+ AES->AES_CR = AES_CR_START;
+
+ while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY);
+
+ sama_aes_lld_get_output((uint32_t *) ((cxt->out) + i));
+ }
+ }
+ else
+ {
+ sama_gcm_lld_process_dma(cryp,cxt);
+ }
+
+ while ((AES->AES_ISR & AES_ISR_TAGRDY) != AES_ISR_TAGRDY);
+
+ ref32 = (uint32_t*)cxt->authtag;
+
+ for (i = 0; i < 4; i++) {
+ ref32[i] =AES->AES_TAGR[i];
+ }
+
+
+ }
+ osalMutexUnlock(&cryp->mutex);
+
+ return ret;
+
+}
+
+
+#endif
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h
new file mode 100644
index 000000000..1ce7c3c19
--- /dev/null
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h
@@ -0,0 +1,25 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed 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.
+*/
+#ifndef CRYPTOLIB_LLD_SAMA_GCM_H_
+#define CRYPTOLIB_LLD_SAMA_GCM_H_
+
+
+
+cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt);
+
+
+
+#endif /* CRYPTOLIB_LLD_SAMA_GCM_H_ */
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c
index 5f1c62339..01209bc6e 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c
@@ -677,13 +677,13 @@ cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp,
cryerror_t ret = CRY_NOERROR;
aesparams params;
+
if(key_id != 0 )
return CRY_ERR_INV_KEY_ID;
if (!(cryp->enabledPer & AES_PER)) {
cryp->enabledPer |= AES_PER;
- pmcEnableAES()
- ;
+ pmcEnableAES();
}
params.encrypt = 1;
@@ -740,8 +740,7 @@ cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
if (!(cryp->enabledPer & AES_PER)) {
cryp->enabledPer |= AES_PER;
- pmcEnableAES()
- ;
+ pmcEnableAES();
}
params.encrypt = 0;
@@ -787,6 +786,9 @@ cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
*
* @notapi
*/
+
+uint8_t gcmbuff[32*2];
+
cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
crykey_t key_id,
size_t size,
@@ -797,17 +799,36 @@ cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
const uint8_t *aad,
uint8_t *authtag) {
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
- (void)aadsize;
- (void)aad;
- (void)authtag;
-
- return CRY_ERR_INV_ALGO;
+ cryerror_t ret = CRY_NOERROR;
+ cgmcontext ctx;
+
+ if (key_id != 0)
+ return CRY_ERR_INV_KEY_ID;
+
+ if (!(cryp->enabledPer & AES_PER)) {
+ cryp->enabledPer |= AES_PER;
+ pmcEnableAES();
+ }
+
+ ctx.params.encrypt = 1;
+ ctx.params.block_size = 16;
+ ctx.params.mode = AES_MR_OPMOD_GCM;
+ ctx.params.iv = iv;
+
+ ctx.in = (uint8_t *)in;
+ ctx.out = out;
+ ctx.c_size = size;
+ ctx.aadsize = aadsize;
+ ctx.aad = (uint8_t *)aad;
+ ctx.authtag = authtag;
+
+
+
+ ret = sama_gcm_lld_process(cryp, &ctx);
+
+
+ return ret;
+
}
/**
@@ -851,17 +872,35 @@ cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp,
const uint8_t *aad,
uint8_t *authtag) {
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
- (void)aadsize;
- (void)aad;
- (void)authtag;
-
- return CRY_ERR_INV_ALGO;
+ cryerror_t ret = CRY_NOERROR;
+ cgmcontext ctx;
+
+ if (key_id != 0)
+ return CRY_ERR_INV_KEY_ID;
+
+ if (!(cryp->enabledPer & AES_PER)) {
+ cryp->enabledPer |= AES_PER;
+ pmcEnableAES();
+ }
+
+ ctx.params.encrypt = 0;
+ ctx.params.block_size = 16;
+ ctx.params.mode = AES_MR_OPMOD_GCM;
+ ctx.params.iv = iv;
+
+ ctx.in =(uint8_t *) in;
+ ctx.out = out;
+ ctx.c_size = size;
+ ctx.aadsize = aadsize;
+ ctx.aad = (uint8_t *)aad;
+ ctx.authtag = authtag;
+
+
+
+ ret = sama_gcm_lld_process(cryp, &ctx);
+
+ return ret;
+
}
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
index 7087e1ead..e6c08ca68 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
@@ -40,7 +40,7 @@
#define CRY_LLD_SUPPORTS_AES_CBC TRUE
#define CRY_LLD_SUPPORTS_AES_CFB TRUE
#define CRY_LLD_SUPPORTS_AES_CTR TRUE
-#define CRY_LLD_SUPPORTS_AES_GCM FALSE
+#define CRY_LLD_SUPPORTS_AES_GCM TRUE
#define CRY_LLD_SUPPORTS_DES TRUE
#define CRY_LLD_SUPPORTS_DES_ECB TRUE
#define CRY_LLD_SUPPORTS_DES_CBC TRUE
@@ -84,6 +84,21 @@ typedef struct
const uint8_t *iv;
}aesparams;
+typedef struct
+{
+ aesparams params;
+
+
+ size_t aadsize;
+ size_t c_size;
+ uint8_t *in;
+ uint8_t *out;
+
+ uint8_t * aad;
+ uint8_t *authtag;
+
+}cgmcontext;
+
typedef enum {
TRANSFER_DMA = 0,
TRANSFER_POLLING,
diff --git a/test/crypto/configuration.xml b/test/crypto/configuration.xml
index dc894e692..846702494 100644
--- a/test/crypto/configuration.xml
+++ b/test/crypto/configuration.xml
@@ -63,6 +63,13 @@ extern void cryptoTest_printArray32(bool isLE,const uint32_t *a,size_t len);
#define SHA_LEN_2 64
#define SHA_LEN_3 128
+#define TEST_GCM_KEY1_LEN 32
+#define TEST_P_LEN 60
+#define TEST_A_LEN 20
+#define TEST_IV1_LEN 12
+#define TEST_CL_LEN 60
+#define TEST_TL_LEN 16
+
extern const char test_plain_data[TEST_DATA_BYTE_LEN];
extern uint32_t msg_clear[TEST_MSG_DATA_WORD_LEN];
extern uint32_t msg_encrypted[TEST_MSG_DATA_WORD_LEN];
@@ -73,6 +80,9 @@ extern const uint8_t sha_msg0[SHA_LEN_0];
extern const uint8_t sha_msg1[SHA_LEN_1];
extern const uint8_t sha_msg2[SHA_LEN_2];
extern const uint8_t sha_msg3[SHA_LEN_3];
+
+
+
]]></value>
</global_definitions>
<global_code>
@@ -128,6 +138,7 @@ const uint8_t sha_msg2[SHA_LEN_2] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
const uint8_t sha_msg3[SHA_LEN_3] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
ALIGNED_VAR(4) uint32_t msg_clear[TEST_MSG_DATA_WORD_LEN];
ALIGNED_VAR(4) uint32_t msg_encrypted[TEST_MSG_DATA_WORD_LEN];
ALIGNED_VAR(4) uint32_t msg_decrypted[TEST_MSG_DATA_WORD_LEN];
@@ -2292,6 +2303,9 @@ for (int i = 0; i < TEST_DATA_WORD_LEN; i++) {
</cases>
</sequence>
+
+
+
<sequence>
<type index="0">
<value>Internal Tests</value>
@@ -3286,9 +3300,348 @@ for (int i = 0; i < 16; i++) {
</steps>
</case>
- </cases>
+ </cases>
</sequence>
- </sequences>
+
+<sequence>
+ <type index="0">
+ <value>Internal Tests</value>
+ </type>
+ <brief>
+ <value>GCM</value>
+ </brief>
+ <description>
+ <value>GCM testing</value>
+ </description>
+ <condition>
+ <value />
+ </condition>
+ <shared_code>
+ <value><![CDATA[
+#include <string.h>
+#include "ref_gcm.h"
+#define plaintext msg_clear
+#define cypher msg_encrypted
+#define authtag msg_decrypted
+
+static const CRYConfig config_Polling=
+{
+ TRANSFER_POLLING,
+ 0
+};
+
+static const CRYConfig config_DMA=
+{
+ TRANSFER_DMA,
+ 0
+};
+
+struct test_el_t
+{
+ uint32_t size;
+ const uint8_t * data;
+
+};
+struct test_gcm_t
+{
+ struct test_el_t key;
+ struct test_el_t p;
+ struct test_el_t iv;
+ struct test_el_t aad;
+ struct test_el_t c;
+ struct test_el_t t;
+
+};
+#define TEST_GCM_LEN 3
+
+const struct test_gcm_t test_gcm_k[TEST_GCM_LEN]={
+
+ { {K3_LEN,K3},{P3_LEN,P3},{IV3_LEN,IV3},{AAD3_LEN,A3},{C3_LEN,C3},{T3_LEN,T3} },
+ { {K4_LEN,K4},{P4_LEN,P4},{IV4_LEN,IV4},{AAD4_LEN,A4},{C4_LEN,C4},{T4_LEN,T4} },
+ { {K5_LEN,K5},{P5_LEN,P5},{IV5_LEN,IV5},{AAD5_LEN,A5},{C5_LEN,C5},{T5_LEN,T5} }
+};
+
+
+
+ ]]></value>
+ </shared_code>
+ <cases>
+ <case>
+ <brief>
+ <value>GCM Polling</value>
+ </brief>
+ <description>
+ <value>testing GCM in polled mode</value>
+ </description>
+ <condition>
+ <value />
+ </condition>
+ <various_code>
+ <setup_code>
+ <value><![CDATA[
+ memset(cypher, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ memset(authtag, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ cryStart(&CRYD1, &config_Polling);
+
+ ]]></value>
+ </setup_code>
+ <teardown_code>
+ <value><![CDATA[cryStop(&CRYD1);]]></value>
+ </teardown_code>
+ <local_variables>
+ <value><![CDATA[
+cryerror_t ret;
+ uint32_t *ref;
+ uint8_t i,len1,len2;
+]]></value>
+ </local_variables>
+ </various_code>
+ <steps>
+ <step>
+ <description>
+ <value>loading the key, encrypt and decrypt</value>
+ </description>
+ <tags>
+ <value />
+ </tags>
+ <code>
+ <value><![CDATA[
+for (i = 0;i<TEST_GCM_LEN;i++) {
+
+ test_print("gcm test : ");
+ test_printn(i);
+ test_println("");
+ /* loading the key .*/
+
+ {
+ ret = cryLoadTransientKey(&CRYD1, (cryalgorithm_t) cry_algo_aes,test_gcm_k[i].key.size, (uint8_t *) test_gcm_k[i].key.data);
+
+ test_assert(ret == CRY_NOERROR, "failed load transient key");
+ }
+
+ /* Encrypt.*/
+
+ {
+
+ ret = cryEncryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].p.size,
+ test_gcm_k[i].p.data,
+ (uint8_t*)cypher,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed encryption");
+
+ len1 = test_gcm_k[i].c.size/4;
+ len2 = test_gcm_k[i].t.size/4;
+ SHOW_DATA(cypher,len1);
+ SHOW_DATA(authtag,len2);
+
+ ref = (uint32_t*)test_gcm_k[i].c.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == cypher[i], "c mismatch");
+ }
+ ref = (uint32_t*)test_gcm_k[i].t.data;
+
+ for (uint8_t i = 0; i < len2; i++) {
+ test_assert(ref[i] == authtag[i], "t mismatch");
+ }
+
+
+
+ }
+
+ /* Decrypt.*/
+
+ {
+
+
+ memset(plaintext, 0, test_gcm_k[i].p.size);
+
+ ret = cryDecryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].c.size,
+ (uint8_t*)cypher,
+ (uint8_t*)plaintext,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed decryption");
+
+ len1 = test_gcm_k[i].p.size/4;
+ SHOW_DATA(plaintext,len1);
+
+ ref = (uint32_t*)test_gcm_k[i].p.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == plaintext[i], "decrypt plain mismatch");
+ }
+
+
+
+ }
+
+ }
+]]></value>
+ </code>
+ </step>
+
+
+
+
+
+
+
+ </steps>
+ </case>
+
+
+ <case>
+ <brief>
+ <value>GCM DMA</value>
+ </brief>
+ <description>
+ <value>testing GCM in DMA mode</value>
+ </description>
+ <condition>
+ <value />
+ </condition>
+ <various_code>
+ <setup_code>
+ <value><![CDATA[
+ memset(cypher, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ memset(authtag, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ cryStart(&CRYD1, &config_DMA);
+
+ ]]></value>
+ </setup_code>
+ <teardown_code>
+ <value><![CDATA[cryStop(&CRYD1);]]></value>
+ </teardown_code>
+ <local_variables>
+ <value><![CDATA[
+cryerror_t ret;
+ uint32_t *ref;
+ uint8_t i,len1,len2;
+]]></value>
+ </local_variables>
+ </various_code>
+ <steps>
+ <step>
+ <description>
+ <value>loading the key, encrypt and decrypt</value>
+ </description>
+ <tags>
+ <value />
+ </tags>
+ <code>
+ <value><![CDATA[
+for (i = 0;i<TEST_GCM_LEN;i++) {
+
+ test_print("gcm test : ");
+ test_printn(i);
+ test_println("");
+ /* loading the key .*/
+
+ {
+ ret = cryLoadTransientKey(&CRYD1, (cryalgorithm_t) cry_algo_aes,test_gcm_k[i].key.size, (uint8_t *) test_gcm_k[i].key.data);
+
+ test_assert(ret == CRY_NOERROR, "failed load transient key");
+ }
+
+ /* Encrypt.*/
+
+ {
+
+ ret = cryEncryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].p.size,
+ test_gcm_k[i].p.data,
+ (uint8_t*)cypher,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed encryption");
+
+ len1 = test_gcm_k[i].c.size/4;
+ len2 = test_gcm_k[i].t.size/4;
+ SHOW_DATA(cypher,len1);
+ SHOW_DATA(authtag,len2);
+
+ ref = (uint32_t*)test_gcm_k[i].c.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == cypher[i], "c mismatch");
+ }
+ ref = (uint32_t*)test_gcm_k[i].t.data;
+
+ for (uint8_t i = 0; i < len2; i++) {
+ test_assert(ref[i] == authtag[i], "t mismatch");
+ }
+
+
+
+ }
+
+ /* Decrypt.*/
+
+ {
+
+
+ memset(plaintext, 0, test_gcm_k[i].p.size);
+
+ ret = cryDecryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].c.size,
+ (uint8_t*)cypher,
+ (uint8_t*)plaintext,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed decryption");
+
+ len1 = test_gcm_k[i].p.size/4;
+ SHOW_DATA(plaintext,len1);
+
+ ref = (uint32_t*)test_gcm_k[i].p.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == plaintext[i], "decrypt plain mismatch");
+ }
+
+
+
+ }
+
+ }
+]]></value>
+ </code>
+ </step>
+
+
+
+
+
+
+
+ </steps>
+ </case>
+
+
+ </cases>
+ </sequence>
+
+ </sequences>
</instance>
</instances>
<exportedFeatures />
diff --git a/test/crypto/crypto_test.mk b/test/crypto/crypto_test.mk
index 0d7310271..1e53235f3 100644
--- a/test/crypto/crypto_test.mk
+++ b/test/crypto/crypto_test.mk
@@ -3,13 +3,15 @@ TESTSRC += ${CHIBIOS}/test/crypto/source/test/cry_test_root.c \
${CHIBIOS}/test/crypto/source/testref/ref_aes.c \
${CHIBIOS}/test/crypto/source/testref/ref_des.c \
${CHIBIOS}/test/crypto/source/testref/ref_sha.c \
+ ${CHIBIOS}/test/crypto/source/testref/ref_gcm.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_001.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_002.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_003.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_004.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_005.c \
${CHIBIOS}/test/crypto/source/test/cry_test_sequence_006.c \
- ${CHIBIOS}/test/crypto/source/test/cry_test_sequence_007.c
+ ${CHIBIOS}/test/crypto/source/test/cry_test_sequence_007.c \
+ ${CHIBIOS}/test/crypto/source/test/cry_test_sequence_008.c
# Required include directories
TESTINC += ${CHIBIOS}/test/crypto/source/testref \
${CHIBIOS}/test/crypto/source/test
diff --git a/test/crypto/source/test/cry_test_root.c b/test/crypto/source/test/cry_test_root.c
index 519e1fa73..9c8feb713 100644
--- a/test/crypto/source/test/cry_test_root.c
+++ b/test/crypto/source/test/cry_test_root.c
@@ -28,6 +28,7 @@
* - @subpage cry_test_sequence_005
* - @subpage cry_test_sequence_006
* - @subpage cry_test_sequence_007
+ * - @subpage cry_test_sequence_008
* .
*/
@@ -56,6 +57,7 @@ const testsequence_t * const cry_test_suite_array[] = {
&cry_test_sequence_005,
&cry_test_sequence_006,
&cry_test_sequence_007,
+ &cry_test_sequence_008,
NULL
};
@@ -122,6 +124,7 @@ const uint8_t sha_msg2[SHA_LEN_2] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
const uint8_t sha_msg3[SHA_LEN_3] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
ALIGNED_VAR(4) uint32_t msg_clear[TEST_MSG_DATA_WORD_LEN];
ALIGNED_VAR(4) uint32_t msg_encrypted[TEST_MSG_DATA_WORD_LEN];
ALIGNED_VAR(4) uint32_t msg_decrypted[TEST_MSG_DATA_WORD_LEN];
diff --git a/test/crypto/source/test/cry_test_root.h b/test/crypto/source/test/cry_test_root.h
index f33cb5c1a..110dd851f 100644
--- a/test/crypto/source/test/cry_test_root.h
+++ b/test/crypto/source/test/cry_test_root.h
@@ -31,6 +31,7 @@
#include "cry_test_sequence_005.h"
#include "cry_test_sequence_006.h"
#include "cry_test_sequence_007.h"
+#include "cry_test_sequence_008.h"
#if !defined(__DOXYGEN__)
@@ -75,6 +76,13 @@ extern void cryptoTest_printArray32(bool isLE,const uint32_t *a,size_t len);
#define SHA_LEN_2 64
#define SHA_LEN_3 128
+#define TEST_GCM_KEY1_LEN 32
+#define TEST_P_LEN 60
+#define TEST_A_LEN 20
+#define TEST_IV1_LEN 12
+#define TEST_CL_LEN 60
+#define TEST_TL_LEN 16
+
extern const char test_plain_data[TEST_DATA_BYTE_LEN];
extern uint32_t msg_clear[TEST_MSG_DATA_WORD_LEN];
extern uint32_t msg_encrypted[TEST_MSG_DATA_WORD_LEN];
@@ -86,6 +94,9 @@ extern const uint8_t sha_msg1[SHA_LEN_1];
extern const uint8_t sha_msg2[SHA_LEN_2];
extern const uint8_t sha_msg3[SHA_LEN_3];
+
+
+
#endif /* !defined(__DOXYGEN__) */
#endif /* CRY_TEST_ROOT_H */
diff --git a/test/crypto/source/test/cry_test_sequence_008.c b/test/crypto/source/test/cry_test_sequence_008.c
new file mode 100644
index 000000000..d22d6b020
--- /dev/null
+++ b/test/crypto/source/test/cry_test_sequence_008.c
@@ -0,0 +1,357 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed 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.
+*/
+
+#include "hal.h"
+#include "cry_test_root.h"
+
+/**
+ * @file cry_test_sequence_008.c
+ * @brief Test Sequence 008 code.
+ *
+ * @page cry_test_sequence_008 [8] GCM
+ *
+ * File: @ref cry_test_sequence_008.c
+ *
+ * <h2>Description</h2>
+ * GCM testing.
+ *
+ * <h2>Test Cases</h2>
+ * - @subpage cry_test_008_001
+ * - @subpage cry_test_008_002
+ * .
+ */
+
+/****************************************************************************
+ * Shared code.
+ ****************************************************************************/
+
+#include <string.h>
+#include "ref_gcm.h"
+#define plaintext msg_clear
+#define cypher msg_encrypted
+#define authtag msg_decrypted
+
+static const CRYConfig config_Polling=
+{
+ TRANSFER_POLLING,
+ 0
+};
+
+static const CRYConfig config_DMA=
+{
+ TRANSFER_DMA,
+ 0
+};
+
+struct test_el_t
+{
+ uint32_t size;
+ const uint8_t * data;
+
+};
+struct test_gcm_t
+{
+ struct test_el_t key;
+ struct test_el_t p;
+ struct test_el_t iv;
+ struct test_el_t aad;
+ struct test_el_t c;
+ struct test_el_t t;
+
+};
+#define TEST_GCM_LEN 3
+
+const struct test_gcm_t test_gcm_k[TEST_GCM_LEN]={
+
+ { {K3_LEN,K3},{P3_LEN,P3},{IV3_LEN,IV3},{AAD3_LEN,A3},{C3_LEN,C3},{T3_LEN,T3} },
+ { {K4_LEN,K4},{P4_LEN,P4},{IV4_LEN,IV4},{AAD4_LEN,A4},{C4_LEN,C4},{T4_LEN,T4} },
+ { {K5_LEN,K5},{P5_LEN,P5},{IV5_LEN,IV5},{AAD5_LEN,A5},{C5_LEN,C5},{T5_LEN,T5} }
+};
+
+
+
+
+
+/****************************************************************************
+ * Test cases.
+ ****************************************************************************/
+
+/**
+ * @page cry_test_008_001 [8.1] GCM Polling
+ *
+ * <h2>Description</h2>
+ * testing GCM in polled mode.
+ *
+ * <h2>Test Steps</h2>
+ * - [8.1.1] loading the key, encrypt and decrypt.
+ * .
+ */
+
+static void cry_test_008_001_setup(void) {
+ memset(cypher, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ memset(authtag, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ cryStart(&CRYD1, &config_Polling);
+
+
+}
+
+static void cry_test_008_001_teardown(void) {
+ cryStop(&CRYD1);
+}
+
+static void cry_test_008_001_execute(void) {
+ cryerror_t ret;
+ uint32_t *ref;
+ uint8_t i,len1,len2;
+
+ /* [8.1.1] loading the key, encrypt and decrypt.*/
+ test_set_step(1);
+ {
+ for (i = 0;i<TEST_GCM_LEN;i++) {
+
+ test_print("gcm test : ");
+ test_printn(i);
+ test_println("");
+ /* loading the key .*/
+
+ {
+ ret = cryLoadTransientKey(&CRYD1, (cryalgorithm_t) cry_algo_aes,test_gcm_k[i].key.size, (uint8_t *) test_gcm_k[i].key.data);
+
+ test_assert(ret == CRY_NOERROR, "failed load transient key");
+ }
+
+ /* Encrypt.*/
+
+ {
+
+ ret = cryEncryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].p.size,
+ test_gcm_k[i].p.data,
+ (uint8_t*)cypher,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed encryption");
+
+ len1 = test_gcm_k[i].c.size/4;
+ len2 = test_gcm_k[i].t.size/4;
+ SHOW_DATA(cypher,len1);
+ SHOW_DATA(authtag,len2);
+
+ ref = (uint32_t*)test_gcm_k[i].c.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == cypher[i], "c mismatch");
+ }
+ ref = (uint32_t*)test_gcm_k[i].t.data;
+
+ for (uint8_t i = 0; i < len2; i++) {
+ test_assert(ref[i] == authtag[i], "t mismatch");
+ }
+
+
+
+ }
+
+ /* Decrypt.*/
+
+ {
+
+
+ memset(plaintext, 0, test_gcm_k[i].p.size);
+
+ ret = cryDecryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].c.size,
+ (uint8_t*)cypher,
+ (uint8_t*)plaintext,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed decryption");
+
+ len1 = test_gcm_k[i].p.size/4;
+ SHOW_DATA(plaintext,len1);
+
+ ref = (uint32_t*)test_gcm_k[i].p.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == plaintext[i], "decrypt plain mismatch");
+ }
+
+
+
+ }
+
+ }
+ }
+}
+
+static const testcase_t cry_test_008_001 = {
+ "GCM Polling",
+ cry_test_008_001_setup,
+ cry_test_008_001_teardown,
+ cry_test_008_001_execute
+};
+
+/**
+ * @page cry_test_008_002 [8.2] GCM DMA
+ *
+ * <h2>Description</h2>
+ * testing GCM in DMA mode.
+ *
+ * <h2>Test Steps</h2>
+ * - [8.2.1] loading the key, encrypt and decrypt.
+ * .
+ */
+
+static void cry_test_008_002_setup(void) {
+ memset(cypher, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ memset(authtag, 0xff, TEST_MSG_DATA_BYTE_LEN);
+ cryStart(&CRYD1, &config_DMA);
+
+
+}
+
+static void cry_test_008_002_teardown(void) {
+ cryStop(&CRYD1);
+}
+
+static void cry_test_008_002_execute(void) {
+ cryerror_t ret;
+ uint32_t *ref;
+ uint8_t i,len1,len2;
+
+ /* [8.2.1] loading the key, encrypt and decrypt.*/
+ test_set_step(1);
+ {
+ for (i = 0;i<TEST_GCM_LEN;i++) {
+
+ test_print("gcm test : ");
+ test_printn(i);
+ test_println("");
+ /* loading the key .*/
+
+ {
+ ret = cryLoadTransientKey(&CRYD1, (cryalgorithm_t) cry_algo_aes,test_gcm_k[i].key.size, (uint8_t *) test_gcm_k[i].key.data);
+
+ test_assert(ret == CRY_NOERROR, "failed load transient key");
+ }
+
+ /* Encrypt.*/
+
+ {
+
+ ret = cryEncryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].p.size,
+ test_gcm_k[i].p.data,
+ (uint8_t*)cypher,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed encryption");
+
+ len1 = test_gcm_k[i].c.size/4;
+ len2 = test_gcm_k[i].t.size/4;
+ SHOW_DATA(cypher,len1);
+ SHOW_DATA(authtag,len2);
+
+ ref = (uint32_t*)test_gcm_k[i].c.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == cypher[i], "c mismatch");
+ }
+ ref = (uint32_t*)test_gcm_k[i].t.data;
+
+ for (uint8_t i = 0; i < len2; i++) {
+ test_assert(ref[i] == authtag[i], "t mismatch");
+ }
+
+
+
+ }
+
+ /* Decrypt.*/
+
+ {
+
+
+ memset(plaintext, 0, test_gcm_k[i].p.size);
+
+ ret = cryDecryptAES_GCM(&CRYD1,
+ 0,
+ test_gcm_k[i].c.size,
+ (uint8_t*)cypher,
+ (uint8_t*)plaintext,
+ test_gcm_k[i].iv.data,
+ test_gcm_k[i].aad.size,
+ test_gcm_k[i].aad.data,
+ (uint8_t*)authtag);
+
+ test_assert(ret == CRY_NOERROR, "failed decryption");
+
+ len1 = test_gcm_k[i].p.size/4;
+ SHOW_DATA(plaintext,len1);
+
+ ref = (uint32_t*)test_gcm_k[i].p.data;
+
+ for (uint8_t i = 0; i < len1; i++) {
+ test_assert(ref[i] == plaintext[i], "decrypt plain mismatch");
+ }
+
+
+
+ }
+
+ }
+ }
+}
+
+static const testcase_t cry_test_008_002 = {
+ "GCM DMA",
+ cry_test_008_002_setup,
+ cry_test_008_002_teardown,
+ cry_test_008_002_execute
+};
+
+/****************************************************************************
+ * Exported data.
+ ****************************************************************************/
+
+/**
+ * @brief Array of test cases.
+ */
+const testcase_t * const cry_test_sequence_008_array[] = {
+ &cry_test_008_001,
+ &cry_test_008_002,
+ NULL
+};
+
+/**
+ * @brief GCM.
+ */
+const testsequence_t cry_test_sequence_008 = {
+ "GCM",
+ cry_test_sequence_008_array
+};
diff --git a/test/crypto/source/test/cry_test_sequence_008.h b/test/crypto/source/test/cry_test_sequence_008.h
new file mode 100644
index 000000000..1c282ade7
--- /dev/null
+++ b/test/crypto/source/test/cry_test_sequence_008.h
@@ -0,0 +1,27 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed 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.
+*/
+
+/**
+ * @file cry_test_sequence_008.h
+ * @brief Test Sequence 008 header.
+ */
+
+#ifndef CRY_TEST_SEQUENCE_008_H
+#define CRY_TEST_SEQUENCE_008_H
+
+extern const testsequence_t cry_test_sequence_008;
+
+#endif /* CRY_TEST_SEQUENCE_008_H */
diff --git a/test/crypto/source/testref/ref_gcm.c b/test/crypto/source/testref/ref_gcm.c
new file mode 100644
index 000000000..74b3e8444
--- /dev/null
+++ b/test/crypto/source/testref/ref_gcm.c
@@ -0,0 +1,77 @@
+
+#include "hal.h"
+#include "ref_gcm.h"
+
+
+///////
+// http://csrc.nist.gov/groups/STM/cavp/gcmtestvectors.zip gcmEncryptExtIV128.rsp
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 128]
+// [AADlen = 128]
+// [Taglen = 128]
+// Count = 0
+// K: c939cc13397c1d37de6ae0e1cb7c423c
+// IV: b3d8cc017cbb89b39e0f67e2
+// P: c3b3c41f113a31b73d9a5cd432103069
+// AAD: 24825602bd12a984e0092d3e448eda5f
+// C: 93fe7d9e9bfd10348a5606e5cafa7354
+// AT: 0032a1dc85f1c9786925a2e71d8272dd
+///////
+const uint8_t K3[] = {0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37, 0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c};
+const uint8_t IV3[] = {0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3, 0x9e, 0x0f, 0x67, 0xe2,
+ 0x00,0x00,0x00,0x01};
+const uint8_t P3[] = {0xc3, 0xb3, 0xc4, 0x1f, 0x11, 0x3a, 0x31, 0xb7, 0x3d, 0x9a, 0x5c, 0xd4, 0x32, 0x10, 0x30, 0x69};
+const uint8_t A3[] = {0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84, 0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f};
+#define A3_len sizeof(A3)
+const uint8_t C3[] = {0x93, 0xfe, 0x7d, 0x9e, 0x9b, 0xfd, 0x10, 0x34, 0x8a, 0x56, 0x06, 0xe5, 0xca, 0xfa, 0x73, 0x54};
+const uint8_t T3[] = {0x00, 0x32, 0xa1, 0xdc, 0x85, 0xf1, 0xc9, 0x78, 0x69, 0x25, 0xa2, 0xe7, 0x1d, 0x82, 0x72, 0xdd};
+
+///////
+// http://csrc.nist.gov/groups/STM/cavp/gcmtestvectors.zip gcmEncryptExtIV128.rsp
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 256]
+// [AADlen = 128]
+// [Taglen = 128]
+// Count = 0
+// K = 298efa1ccf29cf62ae6824bfc19557fc
+// IV = 6f58a93fe1d207fae4ed2f6d
+// P = cc38bccd6bc536ad919b1395f5d63801f99f8068d65ca5ac63872daf16b93901
+// AAD = 021fafd238463973ffe80256e5b1c6b1
+// C = dfce4e9cd291103d7fe4e63351d9e79d3dfd391e3267104658212da96521b7db
+// T = 542465ef599316f73a7a560509a2d9f2
+///////
+const uint8_t K4[] = {0x29, 0x8e, 0xfa, 0x1c, 0xcf, 0x29, 0xcf, 0x62, 0xae, 0x68, 0x24, 0xbf, 0xc1, 0x95, 0x57, 0xfc};
+const uint8_t IV4[] = {0x6f, 0x58, 0xa9, 0x3f, 0xe1, 0xd2, 0x07, 0xfa, 0xe4, 0xed, 0x2f, 0x6d,
+ 0x00,0x00,0x00,0x01};
+const uint8_t P4[] = {0xcc, 0x38, 0xbc, 0xcd, 0x6b, 0xc5, 0x36, 0xad, 0x91, 0x9b, 0x13, 0x95, 0xf5, 0xd6, 0x38, 0x01, 0xf9, 0x9f, 0x80, 0x68, 0xd6, 0x5c, 0xa5, 0xac, 0x63, 0x87, 0x2d, 0xaf, 0x16, 0xb9, 0x39, 0x01};
+const uint8_t A4[] = {0x02, 0x1f, 0xaf, 0xd2, 0x38, 0x46, 0x39, 0x73, 0xff, 0xe8, 0x02, 0x56, 0xe5, 0xb1, 0xc6, 0xb1};
+const uint8_t C4[] = {0xdf, 0xce, 0x4e, 0x9c, 0xd2, 0x91, 0x10, 0x3d, 0x7f, 0xe4, 0xe6, 0x33, 0x51, 0xd9, 0xe7, 0x9d, 0x3d, 0xfd, 0x39, 0x1e, 0x32, 0x67, 0x10, 0x46, 0x58, 0x21, 0x2d, 0xa9, 0x65, 0x21, 0xb7, 0xdb};
+const uint8_t T4[] = {0x54, 0x24, 0x65, 0xef, 0x59, 0x93, 0x16, 0xf7, 0x3a, 0x7a, 0x56, 0x05, 0x09, 0xa2, 0xd9, 0xf2};
+
+///////
+// http://csrc.nist.gov/groups/STM/cavp/gcmtestvectors.zip gcmEncryptExtIV128.rsp
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 256]
+// [AADlen = 128]
+// [Taglen = 128]
+// Count = 0
+// K = 298efa1ccf29cf62ae6824bfc19557fc
+// IV = 6f58a93fe1d207fae4ed2f6d
+// P = cc38bccd6bc536ad919b1395f5d63801f99f8068d65ca5ac63872daf16b93901
+// AAD = 021fafd238463973ffe80256e5b1c6b1
+// C = dfce4e9cd291103d7fe4e63351d9e79d3dfd391e3267104658212da96521b7db
+// T = 542465ef599316f73a7a560509a2d9f2
+///////
+const uint8_t K5[] = {0x29, 0x8e, 0xfa, 0x1c, 0xcf, 0x29, 0xcf, 0x62, 0xae, 0x68, 0x24, 0xbf, 0xc1, 0x95, 0x57, 0xfc};
+const uint8_t IV5[] = {0x6f, 0x58, 0xa9, 0x3f, 0xe1, 0xd2, 0x07, 0xfa, 0xe4, 0xed, 0x2f, 0x6d,
+ 0x00,0x00,0x00,0x01};
+const uint8_t P5[] = {0xcc, 0x38, 0xbc, 0xcd, 0x6b, 0xc5, 0x36, 0xad, 0x91, 0x9b, 0x13, 0x95, 0xf5, 0xd6, 0x38, 0x01, 0xf9, 0x9f, 0x80, 0x68, 0xd6, 0x5c, 0xa5, 0xac, 0x63, 0x87, 0x2d, 0xaf, 0x16, 0xb9, 0x39, 0x01};
+const uint8_t A5[] = {0x02, 0x1f, 0xaf, 0xd2, 0x38, 0x46, 0x39, 0x73, 0xff, 0xe8, 0x02, 0x56, 0xe5, 0xb1, 0xc6, 0xb1};
+const uint8_t C5[] = {0xdf, 0xce, 0x4e, 0x9c, 0xd2, 0x91, 0x10, 0x3d, 0x7f, 0xe4, 0xe6, 0x33, 0x51, 0xd9, 0xe7, 0x9d, 0x3d, 0xfd, 0x39, 0x1e, 0x32, 0x67, 0x10, 0x46, 0x58, 0x21, 0x2d, 0xa9, 0x65, 0x21, 0xb7, 0xdb};
+const uint8_t T5[] = {0x54, 0x24, 0x65, 0xef, 0x59, 0x93, 0x16, 0xf7, 0x3a, 0x7a, 0x56, 0x05, 0x09, 0xa2, 0xd9, 0xf2};
+
+
+
diff --git a/test/crypto/source/testref/ref_gcm.h b/test/crypto/source/testref/ref_gcm.h
new file mode 100644
index 000000000..cc2d43544
--- /dev/null
+++ b/test/crypto/source/testref/ref_gcm.h
@@ -0,0 +1,82 @@
+#ifndef TEST_REF_GCM_H_
+#define TEST_REF_GCM_H_
+
+
+
+#define K3_LEN 16
+#define P3_LEN 16
+#define IV3_LEN (12+4)
+#define AAD3_LEN 16
+#define C3_LEN 16
+#define T3_LEN 16
+
+extern const uint8_t K3[K3_LEN];
+extern const uint8_t IV3[IV3_LEN];
+extern const uint8_t P3[P3_LEN];
+extern const uint8_t A3[AAD3_LEN];
+extern const uint8_t C3[C3_LEN];
+extern const uint8_t T3[T3_LEN];
+
+///////
+// http://csrc.nist.gov/groups/STM/cavp/gcmtestvectors.zip gcmEncryptExtIV128.rsp
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 256]
+// [AADlen = 128]
+// [Taglen = 128]
+// Count = 0
+// K = 298efa1ccf29cf62ae6824bfc19557fc
+// IV = 6f58a93fe1d207fae4ed2f6d
+// P = cc38bccd6bc536ad919b1395f5d63801f99f8068d65ca5ac63872daf16b93901
+// AAD = 021fafd238463973ffe80256e5b1c6b1
+// C = dfce4e9cd291103d7fe4e63351d9e79d3dfd391e3267104658212da96521b7db
+// T = 542465ef599316f73a7a560509a2d9f2
+///////
+#define K4_LEN 16
+#define P4_LEN 32
+#define IV4_LEN (12+4)
+#define AAD4_LEN 16
+#define C4_LEN 32
+#define T4_LEN 16
+
+extern const uint8_t K4[K4_LEN] ;
+extern const uint8_t IV4[IV4_LEN];
+extern const uint8_t P4[P4_LEN] ;
+extern const uint8_t A4[AAD4_LEN] ;
+extern const uint8_t C4[C4_LEN] ;
+extern const uint8_t T4[T4_LEN] ;
+
+///////
+// http://csrc.nist.gov/groups/STM/cavp/gcmtestvectors.zip gcmEncryptExtIV128.rsp
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 256]
+// [AADlen = 128]
+// [Taglen = 128]
+// Count = 0
+// K = 298efa1ccf29cf62ae6824bfc19557fc
+// IV = 6f58a93fe1d207fae4ed2f6d
+// P = cc38bccd6bc536ad919b1395f5d63801f99f8068d65ca5ac63872daf16b93901
+// AAD = 021fafd238463973ffe80256e5b1c6b1
+// C = dfce4e9cd291103d7fe4e63351d9e79d3dfd391e3267104658212da96521b7db
+// T = 542465ef599316f73a7a560509a2d9f2
+///////
+#define K5_LEN 16
+#define P5_LEN 32
+#define IV5_LEN (12+4)
+#define AAD5_LEN 16
+#define C5_LEN 32
+#define T5_LEN 16
+
+extern const uint8_t K5[K5_LEN] ;
+extern const uint8_t IV5[IV5_LEN];
+extern const uint8_t P5[P5_LEN] ;
+extern const uint8_t A5[AAD5_LEN] ;
+extern const uint8_t C5[C5_LEN] ;
+extern const uint8_t T5[T5_LEN] ;
+
+
+
+
+
+#endif //TEST_REF_GCM_H_