mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-06 15:01:35 +00:00
CR50: add a hardware backed GCM implementation
This change adds hardware support for AES128-GCM along with a subset of NIST test vectors. BRANCH=none BUG=chrome-os-partner:60833 CQ-DEPEND=CL:411535 TEST=tpmtest.py passes Change-Id: I93445684f6a910c35a9117eac6cb19d28067a021 Signed-off-by: nagendra modadugu <ngm@google.com> Reviewed-on: https://chromium-review.googlesource.com/425002 Commit-Ready: Nagendra Modadugu <ngm@google.com> Tested-by: Marius Schilder <mschilder@chromium.org> Tested-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Marius Schilder <mschilder@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
c05d723dcf
commit
bb55470b0e
@@ -228,6 +228,8 @@ static void aes_command_handler(void *cmd_body,
|
||||
uint16_t key_len;
|
||||
uint8_t iv_len;
|
||||
uint8_t *iv;
|
||||
uint8_t aad_len;
|
||||
const uint8_t *aad;
|
||||
enum aes_test_cipher_mode c_mode;
|
||||
enum encrypt_mode e_mode;
|
||||
uint8_t *cmd = (uint8_t *)cmd_body;
|
||||
@@ -262,6 +264,8 @@ static void aes_command_handler(void *cmd_body,
|
||||
* key | key len | key to use
|
||||
* iv_len | 1 | either 0 or 16
|
||||
* iv | 0 or 16 | as defined by iv_len
|
||||
* aad_len | <= 127 | additional authentication data length
|
||||
* aad | aad_len | additional authentication data
|
||||
* text_len | 2 | size of the text to process, big endian
|
||||
* text | text_len | text to encrypt/decrypt
|
||||
*/
|
||||
@@ -277,12 +281,16 @@ static void aes_command_handler(void *cmd_body,
|
||||
cmd += key_len;
|
||||
key_len *= 8;
|
||||
iv_len = *cmd++;
|
||||
if (iv_len && (iv_len != 16)) {
|
||||
if ((c_mode == TEST_MODE_GCM && iv_len == 0) ||
|
||||
(c_mode != TEST_MODE_GCM && iv_len && iv_len != 16)) {
|
||||
CPRINTF("Invalid vector len %d\n", iv_len);
|
||||
return;
|
||||
}
|
||||
iv = cmd;
|
||||
cmd += iv_len;
|
||||
aad_len = *cmd++;
|
||||
aad = cmd;
|
||||
cmd += aad_len;
|
||||
data_len = *cmd++;
|
||||
data_len = data_len * 256 + *cmd++;
|
||||
|
||||
@@ -388,6 +396,80 @@ static void aes_command_handler(void *cmd_body,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEST_MODE_GCM:
|
||||
{
|
||||
if (e_mode == 0) {
|
||||
size_t total;
|
||||
size_t count;
|
||||
struct GCM_CTX ctx;
|
||||
|
||||
DCRYPTO_gcm_init(&ctx, key_local.b, iv_local.b, iv_len);
|
||||
DCRYPTO_gcm_aad(&ctx, aad, aad_len);
|
||||
count = DCRYPTO_gcm_decrypt(
|
||||
&ctx, out_local.b, sizeof(out_local.b),
|
||||
data_local.b, data_len);
|
||||
if (count < 0) {
|
||||
CPRINTF(
|
||||
"%s: gcm decrypt failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
total = count;
|
||||
count = DCRYPTO_gcm_decrypt_final(
|
||||
&ctx, out_local.b + total,
|
||||
sizeof(out_local.b) - total);
|
||||
if (count < 0) {
|
||||
CPRINTF(
|
||||
"%s: gcm decrypt_final failed\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
total += count;
|
||||
count = DCRYPTO_gcm_tag(&ctx, out_local.b + total,
|
||||
sizeof(out_local.b) - total);
|
||||
if (count == 0) {
|
||||
CPRINTF("%s: gcm tag failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
total += count;
|
||||
*response_size = total;
|
||||
} else if (e_mode == 1) {
|
||||
size_t total;
|
||||
size_t count;
|
||||
struct GCM_CTX ctx;
|
||||
|
||||
DCRYPTO_gcm_init(&ctx, key_local.b, iv_local.b, iv_len);
|
||||
DCRYPTO_gcm_aad(&ctx, aad, aad_len);
|
||||
count = DCRYPTO_gcm_encrypt(
|
||||
&ctx, out_local.b, sizeof(out_local.b),
|
||||
data_local.b, data_len);
|
||||
if (count < 0) {
|
||||
CPRINTF(
|
||||
"%s: gcm encrypt failed\n");
|
||||
break;
|
||||
}
|
||||
total = count;
|
||||
count = DCRYPTO_gcm_encrypt_final(
|
||||
&ctx, out_local.b + total,
|
||||
sizeof(out_local.b) - total);
|
||||
if (count < 0) {
|
||||
CPRINTF(
|
||||
"%s: gcm encrypt_final failed\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
total += count;
|
||||
count = DCRYPTO_gcm_tag(
|
||||
&ctx, out_local.b + total,
|
||||
sizeof(out_local.b) - total);
|
||||
if (count == 0) {
|
||||
CPRINTF("%s: gcm tag failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
total += count;
|
||||
*response_size = total;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEST_MODE_OFB:
|
||||
if (e_mode == 0) {
|
||||
if (_cpri__AESDecryptOFB(
|
||||
|
||||
@@ -37,6 +37,7 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/bn.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/bn_hw.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/compare.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/dcrypto_runtime.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/gcm.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/hkdf.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/hmac.o
|
||||
chip-$(CONFIG_DCRYPTO)+= dcrypto/key_ladder.o
|
||||
|
||||
@@ -55,6 +55,48 @@ void DCRYPTO_aes_read_iv(uint8_t *iv);
|
||||
int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
|
||||
const uint8_t *iv, const uint8_t *in, size_t in_len);
|
||||
|
||||
/* AES-GCM-128 */
|
||||
struct GCM_CTX {
|
||||
union {
|
||||
uint32_t d[4];
|
||||
uint8_t c[16];
|
||||
} block, Ej0;
|
||||
|
||||
uint64_t aad_len;
|
||||
uint64_t count;
|
||||
size_t remainder;
|
||||
};
|
||||
|
||||
/* Initialize the GCM context structure. */
|
||||
void DCRYPTO_gcm_init(struct GCM_CTX *ctx, const uint8_t *key,
|
||||
const uint8_t *iv, size_t iv_len);
|
||||
/* Additional authentication data to include in the tag calculation. */
|
||||
void DCRYPTO_gcm_aad(struct GCM_CTX *ctx, const uint8_t *aad_data, size_t len);
|
||||
/* Encrypt & decrypt return the number of bytes written to out
|
||||
* (always an integral multiple of 16), or -1 on error. These functions
|
||||
* may be called repeatedly with incremental data.
|
||||
*
|
||||
* NOTE: if in_len is not a integral multiple of 16, then out_len must
|
||||
* be atleast in_len - (in_len % 16) + 16 bytes.
|
||||
*/
|
||||
int DCRYPTO_gcm_encrypt(struct GCM_CTX *ctx, uint8_t *out, size_t out_len,
|
||||
const uint8_t *in, size_t in_len);
|
||||
int DCRYPTO_gcm_decrypt(struct GCM_CTX *ctx, uint8_t *out, size_t out_len,
|
||||
const uint8_t *in, size_t in_len);
|
||||
/* Encrypt & decrypt a partial final block, if any. These functions
|
||||
* return the number of bytes written to out (<= 15), or -1 on error.
|
||||
*/
|
||||
int DCRYPTO_gcm_encrypt_final(struct GCM_CTX *ctx,
|
||||
uint8_t *out, size_t out_len);
|
||||
int DCRYPTO_gcm_decrypt_final(struct GCM_CTX *ctx,
|
||||
uint8_t *out, size_t out_len);
|
||||
/* Compute the tag over AAD + encrypt or decrypt data, and return the
|
||||
* number of bytes written to tag. Returns -1 on error.
|
||||
*/
|
||||
int DCRYPTO_gcm_tag(struct GCM_CTX *ctx, uint8_t *tag, size_t tag_len);
|
||||
/* Cleanup secrets. */
|
||||
void DCRYPTO_gcm_finish(struct GCM_CTX *ctx);
|
||||
|
||||
/*
|
||||
* SHA implementation. This abstraction is backed by either a
|
||||
* software or hardware implementation.
|
||||
@@ -76,7 +118,6 @@ const uint8_t *DCRYPTO_SHA384_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest);
|
||||
const uint8_t *DCRYPTO_SHA512_hash(const void *data, uint32_t n,
|
||||
uint8_t *digest);
|
||||
|
||||
/*
|
||||
* HMAC.
|
||||
*/
|
||||
|
||||
345
chip/g/dcrypto/gcm.c
Normal file
345
chip/g/dcrypto/gcm.c
Normal file
@@ -0,0 +1,345 @@
|
||||
/* Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "dcrypto.h"
|
||||
#include "internal.h"
|
||||
#include "registers.h"
|
||||
|
||||
#include "endian.h"
|
||||
|
||||
#include "cryptoc/util.h"
|
||||
|
||||
static void gcm_mul(uint32_t *counter)
|
||||
{
|
||||
int i;
|
||||
volatile uint32_t *p;
|
||||
|
||||
/* Set HASH to zero. */
|
||||
p = GREG32_ADDR(KEYMGR, GCM_HASH_IN0);
|
||||
for (i = 0; i < 4; i++)
|
||||
*p++ = 0;
|
||||
|
||||
/* Initialize GMAC. */
|
||||
p = GREG32_ADDR(KEYMGR, GCM_MAC0);
|
||||
for (i = 0; i < 4; i++)
|
||||
*p++ = counter[i];
|
||||
|
||||
/* Crank GMAC. */
|
||||
GREG32(KEYMGR, GCM_DO_ACC) = 1;
|
||||
|
||||
/* Read GMAC. */
|
||||
p = GREG32_ADDR(KEYMGR, GCM_MAC0);
|
||||
for (i = 0; i < 4; i++)
|
||||
counter[i] = *p++;
|
||||
|
||||
/* Reset GMAC. */
|
||||
p = GREG32_ADDR(KEYMGR, GCM_MAC0);
|
||||
for (i = 0; i < 4; ++i)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
static void gcm_init_iv(
|
||||
const uint8_t *iv, uint32_t iv_len, uint32_t *counter)
|
||||
{
|
||||
|
||||
if (iv_len == 12) {
|
||||
memcpy(counter, iv, 12);
|
||||
counter[3] = 1 << 24;
|
||||
} else {
|
||||
size_t i;
|
||||
uint32_t len = iv_len;
|
||||
uint64_t len0 = len;
|
||||
uint8_t *ctr = (uint8_t *) counter;
|
||||
|
||||
memset(ctr, 0, 16);
|
||||
while (len >= 16) {
|
||||
for (i = 0; i < 16; ++i)
|
||||
ctr[i] ^= iv[i];
|
||||
|
||||
gcm_mul(counter);
|
||||
iv += 16;
|
||||
len -= 16;
|
||||
}
|
||||
if (len) {
|
||||
for (i = 0; i < len; ++i)
|
||||
ctr[i] ^= iv[i];
|
||||
|
||||
gcm_mul(counter);
|
||||
}
|
||||
len0 <<= 3;
|
||||
ctr[8] ^= (uint8_t)(len0 >> 56);
|
||||
ctr[9] ^= (uint8_t)(len0 >> 48);
|
||||
ctr[10] ^= (uint8_t)(len0 >> 40);
|
||||
ctr[11] ^= (uint8_t)(len0 >> 32);
|
||||
ctr[12] ^= (uint8_t)(len0 >> 24);
|
||||
ctr[13] ^= (uint8_t)(len0 >> 16);
|
||||
ctr[14] ^= (uint8_t)(len0 >> 8);
|
||||
ctr[15] ^= (uint8_t)(len0);
|
||||
|
||||
gcm_mul(counter);
|
||||
}
|
||||
}
|
||||
|
||||
void DCRYPTO_gcm_init(struct GCM_CTX *ctx, const uint8_t *key,
|
||||
const uint8_t *iv, size_t iv_len)
|
||||
{
|
||||
int i;
|
||||
const uint32_t zero[4] = {0, 0, 0, 0};
|
||||
uint32_t H[4];
|
||||
uint32_t counter[4];
|
||||
|
||||
memset(ctx, 0, sizeof(struct GCM_CTX));
|
||||
|
||||
/* Initialize AES engine in CTR mode, and set the counter to 0. */
|
||||
DCRYPTO_aes_init(key, 128, (const uint8_t *) zero,
|
||||
CIPHER_MODE_CTR, ENCRYPT_MODE);
|
||||
/* Set H to AES(ZERO). */
|
||||
DCRYPTO_aes_block((const uint8_t *) zero, (uint8_t *) H);
|
||||
|
||||
/* Initialize the GMAC accumulator to ZERO. */
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_MAC(i) = zero[i];
|
||||
|
||||
/* Initialize H. */
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_H(i) = H[i];
|
||||
|
||||
/* Map the IV to a 128-bit counter. */
|
||||
gcm_init_iv(iv, iv_len, counter);
|
||||
|
||||
/* Re-initialize the IV counter. */
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_AES_CTR(i) = counter[i];
|
||||
|
||||
/* Calculate Ej0: encrypt IV counter XOR ZERO. */
|
||||
DCRYPTO_aes_block((const uint8_t *) zero, ctx->Ej0.c);
|
||||
}
|
||||
|
||||
static void gcm_aad_block(const struct GCM_CTX *ctx, const uint32_t *block)
|
||||
{
|
||||
int i;
|
||||
const struct access_helper *p = (struct access_helper *) block;
|
||||
|
||||
if (ctx->aad_len == 0 && ctx->count <= 16) {
|
||||
/* Update GMAC. */
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_MAC(i) = p[i].udata;
|
||||
} else {
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_HASH_IN(i) = p[i].udata;
|
||||
|
||||
/* Crank GMAC. */
|
||||
GREG32(KEYMGR, GCM_DO_ACC) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void DCRYPTO_gcm_aad(struct GCM_CTX *ctx, const uint8_t *aad_data, size_t len)
|
||||
{
|
||||
uint32_t block[4];
|
||||
|
||||
while (len) {
|
||||
size_t count;
|
||||
|
||||
memset(block, 0, sizeof(block));
|
||||
count = MIN(16, len);
|
||||
memcpy(block, aad_data, count);
|
||||
|
||||
gcm_aad_block(ctx, block);
|
||||
ctx->aad_len += count;
|
||||
|
||||
len -= count;
|
||||
aad_data += count;
|
||||
}
|
||||
|
||||
always_memset(block, 0, sizeof(block));
|
||||
}
|
||||
|
||||
int DCRYPTO_gcm_encrypt(struct GCM_CTX *ctx, uint8_t *out, size_t out_len,
|
||||
const uint8_t *in, size_t in_len)
|
||||
{
|
||||
uint8_t *outp = out;
|
||||
|
||||
if (out_len < (in_len & ~0x0F) + ((in_len & 0x0F) ? 16 : 0))
|
||||
return -1;
|
||||
|
||||
/* Process a previous partial block, if any. */
|
||||
if (ctx->remainder) {
|
||||
size_t count = MIN(in_len, 16 - ctx->remainder);
|
||||
|
||||
memcpy(ctx->block.c + ctx->remainder, in, count);
|
||||
ctx->remainder += count;
|
||||
if (ctx->remainder < 16)
|
||||
return 0;
|
||||
|
||||
DCRYPTO_aes_block(ctx->block.c, outp);
|
||||
ctx->count += 16;
|
||||
gcm_aad_block(ctx, (uint32_t *) outp);
|
||||
ctx->remainder = 0;
|
||||
in += count;
|
||||
in_len -= count;
|
||||
outp += 16;
|
||||
}
|
||||
|
||||
while (in_len >= 16) {
|
||||
DCRYPTO_aes_block(in, outp);
|
||||
ctx->count += 16;
|
||||
|
||||
gcm_aad_block(ctx, (uint32_t *) outp);
|
||||
|
||||
in_len -= 16;
|
||||
in += 16;
|
||||
outp += 16;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
memcpy(ctx->block.c, in, in_len);
|
||||
ctx->remainder = in_len;
|
||||
}
|
||||
|
||||
return outp - out;
|
||||
}
|
||||
|
||||
int DCRYPTO_gcm_encrypt_final(struct GCM_CTX *ctx, uint8_t *out, size_t out_len)
|
||||
{
|
||||
if (out_len < ctx->remainder)
|
||||
return -1;
|
||||
|
||||
if (ctx->remainder) {
|
||||
size_t remainder = ctx->remainder;
|
||||
uint8_t out_block[16];
|
||||
|
||||
DCRYPTO_aes_block(ctx->block.c, out_block);
|
||||
ctx->count += ctx->remainder;
|
||||
memcpy(out, out_block, ctx->remainder);
|
||||
|
||||
memset(out_block + ctx->remainder, 0, 16 - ctx->remainder);
|
||||
gcm_aad_block(ctx, (uint32_t *) out_block);
|
||||
ctx->remainder = 0;
|
||||
return remainder;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DCRYPTO_gcm_decrypt(struct GCM_CTX *ctx, uint8_t *out, size_t out_len,
|
||||
const uint8_t *in, size_t in_len)
|
||||
{
|
||||
uint8_t *outp = out;
|
||||
|
||||
if (out_len < (in_len & ~0x0F) + ((in_len & 0x0F) ? 16 : 0))
|
||||
return -1;
|
||||
|
||||
if (ctx->remainder) {
|
||||
size_t count = MIN(in_len, 16 - ctx->remainder);
|
||||
|
||||
memcpy(ctx->block.c + ctx->remainder, in, count);
|
||||
ctx->remainder += count;
|
||||
|
||||
if (ctx->remainder < 16)
|
||||
return 0;
|
||||
|
||||
DCRYPTO_aes_block(ctx->block.c, outp);
|
||||
ctx->remainder = 0;
|
||||
ctx->count += 16;
|
||||
gcm_aad_block(ctx, ctx->block.d);
|
||||
in += count;
|
||||
in_len -= count;
|
||||
outp += count;
|
||||
}
|
||||
|
||||
while (in_len >= 16) {
|
||||
DCRYPTO_aes_block(in, outp);
|
||||
ctx->count += 16;
|
||||
gcm_aad_block(ctx, (uint32_t *) in);
|
||||
in += 16;
|
||||
in_len -= 16;
|
||||
outp += 16;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
memcpy(ctx->block.c, in, in_len);
|
||||
ctx->remainder = in_len;
|
||||
}
|
||||
|
||||
return outp - out;
|
||||
}
|
||||
|
||||
int DCRYPTO_gcm_decrypt_final(struct GCM_CTX *ctx,
|
||||
uint8_t *out, size_t out_len)
|
||||
{
|
||||
if (out_len < ctx->remainder)
|
||||
return -1;
|
||||
|
||||
if (ctx->remainder) {
|
||||
size_t remainder = ctx->remainder;
|
||||
uint8_t out_block[16];
|
||||
|
||||
DCRYPTO_aes_block(ctx->block.c, out_block);
|
||||
ctx->count += ctx->remainder;
|
||||
memcpy(out, out_block, ctx->remainder);
|
||||
|
||||
memset(ctx->block.c + ctx->remainder, 0, 16 - ctx->remainder);
|
||||
gcm_aad_block(ctx, ctx->block.d);
|
||||
ctx->remainder = 0;
|
||||
return remainder;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dcrypto_gcm_len_vector(
|
||||
const struct GCM_CTX *ctx, void *len_vector) {
|
||||
uint64_t aad_be;
|
||||
uint64_t count_be;
|
||||
|
||||
/* Serialize counters to bit-count (big-endian). */
|
||||
aad_be = ctx->aad_len * 8;
|
||||
aad_be = htobe64(aad_be);
|
||||
count_be = ctx->count * 8;
|
||||
count_be = htobe64(count_be);
|
||||
|
||||
memcpy(len_vector, &aad_be, 8);
|
||||
memcpy(((uint8_t *)len_vector) + 8, &count_be, 8);
|
||||
}
|
||||
|
||||
static void dcrypto_gcm_tag(const struct GCM_CTX *ctx,
|
||||
const uint32_t *len_vector, uint32_t *tag) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_HASH_IN(i) = len_vector[i];
|
||||
|
||||
/* Crank GMAC. */
|
||||
GREG32(KEYMGR, GCM_DO_ACC) = 1;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
GR_KEYMGR_GCM_HASH_IN(i) = ctx->Ej0.d[i];
|
||||
|
||||
/* Crank GMAC. */
|
||||
GREG32(KEYMGR, GCM_DO_ACC) = 1;
|
||||
|
||||
/* Read tag. */
|
||||
for (i = 0; i < 4; i++)
|
||||
tag[i] = GR_KEYMGR_GCM_MAC(i);
|
||||
}
|
||||
|
||||
int DCRYPTO_gcm_tag(struct GCM_CTX *ctx, uint8_t *tag, size_t tag_len)
|
||||
{
|
||||
uint32_t len_vector[4];
|
||||
uint32_t local_tag[4];
|
||||
size_t count = MIN(tag_len, sizeof(local_tag));
|
||||
|
||||
dcrypto_gcm_len_vector(ctx, len_vector);
|
||||
dcrypto_gcm_tag(ctx, len_vector, local_tag);
|
||||
|
||||
memcpy(tag, local_tag, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void DCRYPTO_gcm_finish(struct GCM_CTX *ctx)
|
||||
{
|
||||
always_memset(ctx, 0, sizeof(struct GCM_CTX));
|
||||
GREG32(KEYMGR, AES_WIPE_SECRETS) = 1;
|
||||
}
|
||||
@@ -316,6 +316,9 @@ static inline int x_timehs_addr(unsigned int module, unsigned int timer,
|
||||
/* Key manager */
|
||||
#define GR_KEYMGR_AES_KEY(n) REG32(GREG32_ADDR(KEYMGR, AES_KEY0) + (n))
|
||||
#define GR_KEYMGR_AES_CTR(n) REG32(GREG32_ADDR(KEYMGR, AES_CTR0) + (n))
|
||||
#define GR_KEYMGR_GCM_H(n) REG32(GREG32_ADDR(KEYMGR, GCM_H0) + (n))
|
||||
#define GR_KEYMGR_GCM_HASH_IN(n) REG32(GREG32_ADDR(KEYMGR, GCM_HASH_IN0) + (n))
|
||||
#define GR_KEYMGR_GCM_MAC(n) REG32(GREG32_ADDR(KEYMGR, GCM_MAC0) + (n))
|
||||
#define GR_KEYMGR_SHA_HASH(n) REG32(GREG32_ADDR(KEYMGR, SHA_STS_H0) + (n))
|
||||
#define GR_KEYMGR_HKEY_FRR(n) REG32(GREG32_ADDR(KEYMGR, HKEY_FRR0) + (n))
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def get_attribute(tdesc, attr_name, required=True):
|
||||
|
||||
"""
|
||||
# Fields stored in hex format by default.
|
||||
default_hex = ('cipher_text', 'iv', 'key')
|
||||
default_hex = ('aad', 'cipher_text', 'iv', 'key', 'tag')
|
||||
|
||||
data = tdesc.find(attr_name)
|
||||
if data is None:
|
||||
@@ -108,7 +108,7 @@ SUPPORTED_MODES = {
|
||||
}),
|
||||
}
|
||||
|
||||
def crypto_run(node_name, op_type, key, iv, in_text, out_text, tpm):
|
||||
def crypto_run(node_name, op_type, key, iv, aad, in_text, out_text, tpm):
|
||||
"""Perform a basic operation(encrypt or decrypt).
|
||||
|
||||
This function creates an extended command with the requested parameters,
|
||||
@@ -125,6 +125,7 @@ def crypto_run(node_name, op_type, key, iv, in_text, out_text, tpm):
|
||||
directly to the device as a field in the extended command
|
||||
key: a binary string
|
||||
iv: a binary string, might be empty
|
||||
aad: additional authenticated data
|
||||
in_text: a binary string, the input of the encrypt/decrypt operation
|
||||
out_text: a binary string, might be empty, the expected output of the
|
||||
operation. Note that it could be shorter than actual output (padded to
|
||||
@@ -156,6 +157,9 @@ def crypto_run(node_name, op_type, key, iv, in_text, out_text, tpm):
|
||||
cmd += '%c' % len(iv)
|
||||
if iv:
|
||||
cmd += iv
|
||||
cmd += '%c' % len(aad)
|
||||
if aad:
|
||||
cmd += aad
|
||||
cmd += struct.pack('>H', len(in_text))
|
||||
cmd += in_text
|
||||
if tpm.debug_enabled():
|
||||
@@ -203,18 +207,33 @@ def crypto_test(tdesc, tpm):
|
||||
node_name,
|
||||
''.join('%2.2x' % ord(x) for x in key)))
|
||||
iv = get_attribute(tdesc, 'iv', required=False)
|
||||
if iv and len(iv) != 16:
|
||||
if iv and not node_name.startswith('AES:GCM') and len(iv) != 16:
|
||||
raise subcmd.TpmTestError('wrong iv size "%s:%s"' % (
|
||||
node_name,
|
||||
''.join('%2.2x' % ord(x) for x in iv)))
|
||||
clear_text = get_attribute(tdesc, 'clear_text')
|
||||
clear_text = get_attribute(tdesc, 'clear_text', required=False)
|
||||
if clear_text:
|
||||
clear_text_len = get_attribute(tdesc, 'clear_text_len', required=False)
|
||||
if clear_text_len:
|
||||
clear_text = clear_text[:int(clear_text_len)]
|
||||
else:
|
||||
clear_text_len = None
|
||||
if tpm.debug_enabled():
|
||||
print('clear text size', len(clear_text))
|
||||
cipher_text = get_attribute(tdesc, 'cipher_text', required=False)
|
||||
if clear_text_len:
|
||||
cipher_text = cipher_text[:int(clear_text_len)]
|
||||
tag = get_attribute(tdesc, 'tag', required=False)
|
||||
aad = get_attribute(tdesc, 'aad', required=False)
|
||||
if aad:
|
||||
aad_len = get_attribute(tdesc, 'aad_len', required=False)
|
||||
if aad_len:
|
||||
aad = aad[:int(aad_len)]
|
||||
real_cipher_text = crypto_run(node_name, ENCRYPT, key, iv,
|
||||
clear_text, cipher_text, tpm)
|
||||
crypto_run(node_name, DECRYPT, key, iv, real_cipher_text,
|
||||
clear_text, tpm)
|
||||
aad or '', clear_text, cipher_text + tag, tpm)
|
||||
crypto_run(node_name, DECRYPT, key, iv, aad or '',
|
||||
real_cipher_text[:len(real_cipher_text) - len(tag)],
|
||||
clear_text + tag, tpm)
|
||||
print(utils.cursor_back() + 'SUCCESS: %s' % node_name)
|
||||
|
||||
def crypto_tests(tpm, xml_file):
|
||||
|
||||
@@ -39,6 +39,7 @@ Many of the crypto_test elements were borrowed from NIST test vectors.
|
||||
34b58f68 a9e27607 7bdd8e72 8b2b528b
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:ECB128 1">
|
||||
<clear_text format="hex">
|
||||
33221100 77665544 bbaa9988 ffeeddcc
|
||||
@@ -560,4 +561,270 @@ Many of the crypto_test elements were borrowed from NIST test vectors.
|
||||
</iv>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 1">
|
||||
<key>
|
||||
53c372160082fa7a468a6b4c26d0f0f6
|
||||
</key>
|
||||
<iv>
|
||||
05
|
||||
</iv>
|
||||
<tag>
|
||||
21d72a8e745f45f9313db5d88e7ef241
|
||||
</tag>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 2">
|
||||
<key>
|
||||
74b5dd7fd041c2533aedfb3e1c374ec4
|
||||
</key>
|
||||
<iv>
|
||||
3f3a28eee37555c78748fd3e
|
||||
</iv>
|
||||
<tag>
|
||||
f91d6db396e5d5b97f8b3ef8b31c9752
|
||||
</tag>
|
||||
<clear_text format="hex">
|
||||
b442ded5256c646129bd875ca2b9d362
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
a5a4cd2c1eb95c410f2a5c13fdb2c978
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 3">
|
||||
<key>
|
||||
5571dcfeb2002d197598dd3cbaebb90d
|
||||
</key>
|
||||
<iv>
|
||||
f5746ba756171a5cb13883a0
|
||||
</iv>
|
||||
<tag>
|
||||
55c43dd28798d4ceeae817c78429ecbe
|
||||
</tag>
|
||||
<aad>
|
||||
c406d22a557e6e173688a02afa16688859e777fa
|
||||
</aad>
|
||||
<clear_text format="hex">
|
||||
5b433168f1da578848b113c5b5130d8290c42ca7989aa7bdd820f5a6d1393c76
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
0538821592a189da6f1dfc3b564d78878b12d1badedbff4da52fbbef685ec362
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 4">
|
||||
<key>
|
||||
7063be77e2c4718979cbd140eb7fd7e8
|
||||
</key>
|
||||
<iv>
|
||||
190fe0e001bad7fef397a736
|
||||
</iv>
|
||||
<tag>
|
||||
8dcc9f2093ed753666719c8e46d99d70
|
||||
</tag>
|
||||
<aad>
|
||||
1dec437a785a0a9c3365b1a0ab3c21a6
|
||||
</aad>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 5">
|
||||
<key>
|
||||
79e8e399576e683ec585821d2b5ef764
|
||||
</key>
|
||||
<iv>
|
||||
b80addc2a86ada68230d9cad
|
||||
</iv>
|
||||
<tag>
|
||||
10ba4f3f341faf0eaaadbab0855d99e9
|
||||
</tag>
|
||||
<aad>
|
||||
2de468b6a84c444ed9fd3cb2d5ed9f5a21a58a17b0904814f53c73936c5222cf47ee17599a8041658c7a86c6fc099339
|
||||
</aad>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 6">
|
||||
<key>
|
||||
8824a2d45c1dddf8d6a7196c4c9617ca
|
||||
</key>
|
||||
<iv>
|
||||
7f83d5f3041aac22d5d1e025
|
||||
</iv>
|
||||
<tag>
|
||||
f9ac3ef273f8cdd186c526779c6e8248
|
||||
</tag>
|
||||
<aad>
|
||||
24d4c5f1c6963fb88cb28cad470ed2a05a3b025e
|
||||
</aad>
|
||||
<clear_text format="hex">
|
||||
6a01437b97648916e67b45fb2241a5d2
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
ee67bdc2ac5ce9f56eb0e327a8d03130
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 7">
|
||||
<key>
|
||||
635c7cbd562b54b771be0ea088156a33
|
||||
</key>
|
||||
<iv>
|
||||
231f72878e3c9cbabc1a57a5
|
||||
</iv>
|
||||
<tag>
|
||||
2267b59c2e250b0d46ff7bb9f80fb0e4
|
||||
</tag>
|
||||
<aad>
|
||||
7580eca60e37d3a0188959b7483eb9f36251474499b89749a9a67fa84e849f93b7a88a003b4c9f0e28d3191ae743f56bcbfe7b12a517ada1ccfc53ecacecfa266953c7c47daa8e4963ef6a702709004dbae4119b5e3e996c0000d99e
|
||||
</aad>
|
||||
<aad_len>
|
||||
90
|
||||
</aad_len>
|
||||
<clear_text format="hex">
|
||||
bbdd15de6121201ef69aa7e8f3c65aa5
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
c028eb4162d7e4fe612397de80bc63c8
|
||||
</cipher_text>,
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 8">
|
||||
<key>
|
||||
23deefdff02b12c689b50a37734b800e
|
||||
</key>
|
||||
<iv>
|
||||
02a8d6920f679099e279de16
|
||||
</iv>
|
||||
<tag>
|
||||
9982a39d07c5cd680dc3d1941545cd41
|
||||
</tag>
|
||||
<aad>
|
||||
786db1a2c1e61d250e35ce9142f25e5c
|
||||
</aad>
|
||||
<clear_text format="hex">
|
||||
8c0a266478e97d2821756ce9000000d0
|
||||
</clear_text>
|
||||
<clear_text_len>
|
||||
13
|
||||
</clear_text_len>
|
||||
<cipher_text>
|
||||
94de78bf177c848ab4d44936000000d0
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 9">
|
||||
<key>
|
||||
dbb8d3cbce11fbfce60657341a8873cd
|
||||
</key>
|
||||
<iv>
|
||||
68bb62dc5d9aecd041679d75
|
||||
</iv>
|
||||
<tag>
|
||||
b2215a420c5890ea03349188b54b912b
|
||||
</tag>
|
||||
<aad>
|
||||
61b64409f39462fe08bb2ac959b2c17e4edc32b068285f0c636ebe1c478f17c25af32643c280cad3e785348ec852b2e5
|
||||
</aad>
|
||||
<aad_len>
|
||||
48
|
||||
</aad_len>
|
||||
<clear_text format="hex">
|
||||
f53bf8855bd5df982adebfc800000064
|
||||
</clear_text>
|
||||
<clear_text_len>
|
||||
13
|
||||
</clear_text_len>
|
||||
<cipher_text>
|
||||
3b6b6f20ecdf32b040839fd3000000b1
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 10">
|
||||
<key>
|
||||
1007719909c0ab5969bdf2e438b39d86
|
||||
</key>
|
||||
<iv>
|
||||
5ea9a9079c1e82a35132c613
|
||||
</iv>
|
||||
<tag>
|
||||
11d970781a81547ff1706934410c09de
|
||||
</tag>
|
||||
<clear_text format="hex">
|
||||
50c34bf56f4fed1fa85efb6d0bdf060182e636d85cb72562e8f622028359b359
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
59c156056cf34ef8452b60b10920b1261b6175c7c04db6ff9792cad9016a2ccd
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 11">
|
||||
<key>
|
||||
a17cbf8fdd25d52f58621ee9c251fe73
|
||||
</key>
|
||||
<iv>
|
||||
51ea0b20a190977b5eafadcf
|
||||
</iv>
|
||||
<tag>
|
||||
7407867cb93283f8bd6bcea727a77202
|
||||
</tag>
|
||||
<aad>
|
||||
7fc014a4ec0be6e29e40cc9c6f9c899ebb8005e661c807262385f0f71bda9ce61d713a9c09359c1dc9e471176d99b9502e4fd00a10b3d1002a545358ff9fe0960fc82efc2887f88caef094f5a6984fb18b4e23882703f7fb000064b3
|
||||
</aad>
|
||||
<aad_len>
|
||||
90
|
||||
</aad_len>
|
||||
<clear_text format="hex">
|
||||
27e6d33963494b7c42160d840aaefae697dae25b554e1cf602ce57bbc4d40319
|
||||
</clear_text>
|
||||
<cipher_text>
|
||||
f78e67fe95ac696f6d3b55db7aa0d5ad51e1c89da39f6afe1662cda16878b836
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 12">
|
||||
<key>
|
||||
bb5315b6b9954885d01c75298403f8c5
|
||||
</key>
|
||||
<iv>
|
||||
99f963885de564ae5774bd0b
|
||||
</iv>
|
||||
<tag>
|
||||
4a5f9b5dc6c16898d86fbd9c4013f051
|
||||
</tag>
|
||||
<aad>
|
||||
f2b514d9e58cb0d1b39ca53e45725810
|
||||
</aad>
|
||||
<clear_text format="hex">
|
||||
32111b9beac4d01712cf4379adc6693c36973c2e75c9518c55d1454186eee1ddffcac840975c7af1136ad237f34bee7e006d0969
|
||||
</clear_text>
|
||||
<clear_text_len>
|
||||
51
|
||||
</clear_text_len>
|
||||
<cipher_text>
|
||||
63b4faac80258a2b3df11251bc82e085bd49dc89a84f169242d2daa2f2b2a1c3df2f6f695f0279f5a96e143f7de4a37d00654bc3
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
|
||||
<crypto_test name="AES:GCM128 13">
|
||||
<key>
|
||||
2862503caa50f4680c99280936ebe115
|
||||
</key>
|
||||
<iv>
|
||||
90521d81e7578d76c7b67bd8
|
||||
</iv>
|
||||
<tag>
|
||||
fc5e9bbdcd0880a47d4f3a974438722c
|
||||
</tag>
|
||||
<aad>
|
||||
e0c7e2da2bfdd3a319ca4ec0a07851b184cfb503c2280c890ff215a67f42db8a128c69707887efb2fb93110c7416cdb8
|
||||
</aad>
|
||||
<clear_text format="hex">
|
||||
f8a8d0ed19e93328bfe20f744acfde9edc726cc8ef0c4989aa83697b85fc99af7dc85c6c7c8af96327f31b86a86dea1f00ab156a
|
||||
</clear_text>
|
||||
<clear_text_len>
|
||||
51
|
||||
</clear_text_len>
|
||||
<cipher_text>
|
||||
b02514a54b3b8d6005ecd446f0da1dca8920dd2bec5405ae841c2afbdc823dc6abb9dd71490b1f1b7cd22adee773512b00a60a00
|
||||
</cipher_text>
|
||||
</crypto_test>
|
||||
</crypto_tests>
|
||||
|
||||
Reference in New Issue
Block a user