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 <stddef.h>
6 #include <stdint.h>
7 #include <string.h>
8
9 #include <crypto/secret.h>
10 #include <explicit-memory/bytes.h>
11 #include <fbl/algorithm.h>
12 #include <fbl/macros.h>
13 #include <fbl/unique_ptr.h>
14 #include <lib/fdio/debug.h>
15 #include <zircon/errors.h>
16 #include <zircon/status.h>
17 #include <zircon/syscalls.h>
18 #include <zircon/types.h>
19
20 // See note in //zircon/third_party/ulib/uboringssl/rules.mk
21 #define BORINGSSL_NO_CXX
22 #include <openssl/mem.h>
23
24 #define ZXDEBUG 0
25
26 namespace crypto {
27
28 // Public methods
29
Secret()30 Secret::Secret() : buf_(nullptr), len_(0) {}
31
~Secret()32 Secret::~Secret() {
33 Clear();
34 }
35
Allocate(size_t len,uint8_t ** out)36 zx_status_t Secret::Allocate(size_t len, uint8_t** out) {
37 ZX_ASSERT(len != 0 && out);
38
39 Clear();
40 fbl::AllocChecker ac;
41 buf_.reset(new (&ac) uint8_t[len]);
42 if (!ac.check()) {
43 xprintf("failed to allocate %zu bytes\n", len);
44 return ZX_ERR_NO_MEMORY;
45 }
46 memset(buf_.get(), 0, len);
47 len_ = len;
48
49 *out = buf_.get();
50 return ZX_OK;
51 }
52
Generate(size_t len)53 zx_status_t Secret::Generate(size_t len) {
54 ZX_ASSERT(len != 0);
55
56 uint8_t* tmp = nullptr;
57 zx_status_t status = Allocate(len, &tmp);
58 if (status != ZX_OK) {
59 return status;
60 }
61
62 zx_cprng_draw(buf_.get(), len);
63 return ZX_OK;
64 }
65
Clear()66 void Secret::Clear() {
67 if (buf_) {
68 mandatory_memset(buf_.get(), 0, len_);
69 }
70 buf_.reset();
71 len_ = 0;
72 }
73
74 } // namespace crypto
75