1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <limits.h>
6 #include <string.h>
7 
8 #include <crypto/aead.h>
9 #include <crypto/bytes.h>
10 #include <crypto/cipher.h>
11 #include <crypto/digest.h>
12 #include <crypto/hkdf.h>
13 #include <crypto/hmac.h>
14 #include <zircon/types.h>
15 
16 #include "utils.h"
17 
18 namespace crypto {
19 namespace testing {
20 
HexToBuf(const char * hex,uint8_t * buf,size_t max)21 zx_status_t HexToBuf(const char* hex, uint8_t* buf, size_t max) {
22     size_t i = 0;
23     size_t j = 0;
24     uint8_t n;
25     while (j < max) {
26         char c = hex[i];
27         if ('0' <= c && c <= '9') {
28             n = static_cast<uint8_t>(c - '0');
29         } else if ('a' <= c && c <= 'f') {
30             n = static_cast<uint8_t>(c - 'a' + 10);
31         } else if ('A' <= c && c <= 'F') {
32             n = static_cast<uint8_t>(c - 'A' + 10);
33         } else {
34             return ZX_ERR_INVALID_ARGS;
35         }
36         if (i % 2 == 0) {
37             buf[j] = static_cast<uint8_t>(n << 4);
38         } else {
39             buf[j] |= n & 0xF;
40             ++j;
41         }
42         ++i;
43     }
44     return ZX_OK;
45 }
46 
HexToBytes(const char * hex,Bytes * out)47 zx_status_t HexToBytes(const char* hex, Bytes* out) {
48     ZX_DEBUG_ASSERT(hex);
49     ZX_DEBUG_ASSERT(out);
50     zx_status_t rc;
51 
52     size_t len = strlen(hex) / 2;
53     if ((rc = out->Resize(len)) != ZX_OK ||
54         (rc = HexToBuf(hex, out->get(), len)) != ZX_OK) {
55         return rc;
56     }
57 
58     return ZX_OK;
59 }
60 
HexToSecret(const char * hex,Secret * out)61 zx_status_t HexToSecret(const char* hex, Secret* out) {
62     ZX_DEBUG_ASSERT(hex);
63     ZX_DEBUG_ASSERT(out);
64     zx_status_t rc;
65 
66     uint8_t *buf;
67     size_t len = strlen(hex) / 2;
68     if ((rc = out->Allocate(len, &buf)) != ZX_OK ||
69         (rc = HexToBuf(hex, buf, len)) != ZX_OK) {
70         return rc;
71     }
72 
73     return ZX_OK;
74 }
75 
GenerateKeyMaterial(Cipher::Algorithm cipher,Secret * key,Bytes * iv)76 zx_status_t GenerateKeyMaterial(Cipher::Algorithm cipher, Secret* key, Bytes* iv) {
77     zx_status_t rc;
78     ZX_DEBUG_ASSERT(key);
79 
80     size_t key_len;
81     if ((rc = Cipher::GetKeyLen(cipher, &key_len)) != ZX_OK ||
82         (rc = key->Generate(key_len)) != ZX_OK) {
83         return rc;
84     }
85     if (iv) {
86         size_t iv_len;
87         if ((rc = Cipher::GetIVLen(cipher, &iv_len)) != ZX_OK ||
88             (rc = iv->Randomize(iv_len)) != ZX_OK) {
89             return rc;
90         }
91     }
92 
93     return ZX_OK;
94 }
95 
GenerateKeyMaterial(AEAD::Algorithm cipher,Secret * key,Bytes * iv)96 zx_status_t GenerateKeyMaterial(AEAD::Algorithm cipher, Secret* key, Bytes* iv) {
97     zx_status_t rc;
98     ZX_DEBUG_ASSERT(key);
99 
100     size_t key_len;
101     if ((rc = AEAD::GetKeyLen(cipher, &key_len)) != ZX_OK ||
102         (rc = key->Generate(key_len)) != ZX_OK) {
103         return rc;
104     }
105     if (iv) {
106         size_t iv_len;
107         if ((rc = AEAD::GetIVLen(cipher, &iv_len)) != ZX_OK ||
108             (rc = iv->Randomize(iv_len)) != ZX_OK) {
109             return rc;
110         }
111     }
112 
113     return ZX_OK;
114 }
115 
116 } // namespace testing
117 } // namespace crypto
118