blob: 946411cef5b190e2a70ae5dc93ba5fa79c43cc90 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 "utils.h"
#include <limits.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/types.h>
#include "src/security/fcrypto/aead.h"
#include "src/security/fcrypto/bytes.h"
#include "src/security/fcrypto/cipher.h"
#include "src/security/fcrypto/digest.h"
#include "src/security/fcrypto/hkdf.h"
#include "src/security/fcrypto/hmac.h"
namespace crypto {
namespace testing {
zx_status_t HexToBuf(const char* hex, uint8_t* buf, size_t max) {
size_t i = 0;
size_t j = 0;
uint8_t n;
while (j < max) {
char c = hex[i];
if ('0' <= c && c <= '9') {
n = static_cast<uint8_t>(c - '0');
} else if ('a' <= c && c <= 'f') {
n = static_cast<uint8_t>(c - 'a' + 10);
} else if ('A' <= c && c <= 'F') {
n = static_cast<uint8_t>(c - 'A' + 10);
} else {
return ZX_ERR_INVALID_ARGS;
}
if (i % 2 == 0) {
buf[j] = static_cast<uint8_t>(n << 4);
} else {
buf[j] |= n & 0xF;
++j;
}
++i;
}
return ZX_OK;
}
zx_status_t HexToBytes(const char* hex, Bytes* out) {
ZX_DEBUG_ASSERT(hex);
ZX_DEBUG_ASSERT(out);
zx_status_t rc;
size_t len = strlen(hex) / 2;
if ((rc = out->Resize(len)) != ZX_OK || (rc = HexToBuf(hex, out->get(), len)) != ZX_OK) {
return rc;
}
return ZX_OK;
}
zx_status_t HexToSecret(const char* hex, Secret* out) {
ZX_DEBUG_ASSERT(hex);
ZX_DEBUG_ASSERT(out);
zx_status_t rc;
uint8_t* buf;
size_t len = strlen(hex) / 2;
if ((rc = out->Allocate(len, &buf)) != ZX_OK || (rc = HexToBuf(hex, buf, len)) != ZX_OK) {
return rc;
}
return ZX_OK;
}
zx_status_t GenerateKeyMaterial(Cipher::Algorithm cipher, Secret* key, Bytes* iv) {
zx_status_t rc;
ZX_DEBUG_ASSERT(key);
size_t key_len;
if ((rc = Cipher::GetKeyLen(cipher, &key_len)) != ZX_OK ||
(rc = key->Generate(key_len)) != ZX_OK) {
return rc;
}
if (iv) {
size_t iv_len;
if ((rc = Cipher::GetIVLen(cipher, &iv_len)) != ZX_OK ||
(rc = iv->Randomize(iv_len)) != ZX_OK) {
return rc;
}
}
return ZX_OK;
}
zx_status_t GenerateKeyMaterial(AEAD::Algorithm cipher, Secret* key, Bytes* iv) {
zx_status_t rc;
ZX_DEBUG_ASSERT(key);
size_t key_len;
if ((rc = AEAD::GetKeyLen(cipher, &key_len)) != ZX_OK || (rc = key->Generate(key_len)) != ZX_OK) {
return rc;
}
if (iv) {
size_t iv_len;
if ((rc = AEAD::GetIVLen(cipher, &iv_len)) != ZX_OK || (rc = iv->Randomize(iv_len)) != ZX_OK) {
return rc;
}
}
return ZX_OK;
}
bool AllEqual(const Bytes& buf, uint8_t val, zx_off_t off, size_t len) {
for (size_t i = 0; i < len; ++i) {
if (buf[off] != val) {
return false;
}
off++;
}
return true;
}
} // namespace testing
} // namespace crypto