summaryrefslogtreecommitdiffstats
path: root/CryptoPkg/Library/OpensslLib/rand_pool.c
blob: 03047b233e3edb1f66cef16c1ba84a1b6170e22f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/** @file
  OpenSSL_1_1_1b doesn't implement rand_pool_* functions for UEFI.
  The file implement these functions.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "crypto/rand.h"
#include <openssl/aes.h>

#include <Uefi.h>
#include <Library/RngLib.h>

/**
  Calls RandomNumber64 to fill
  a buffer of arbitrary size with random bytes.
  This is a shim layer to RngLib.

  @param[in]   Length        Size of the buffer, in bytes,  to fill with.
  @param[out]  RandBuffer    Pointer to the buffer to store the random result.

  @retval TRUE        Random bytes generation succeeded.
  @retval FALSE       Failed to request random bytes.

**/
STATIC
BOOLEAN
EFIAPI
RandGetBytes (
  IN UINTN   Length,
  OUT UINT8  *RandBuffer
  )
{
  BOOLEAN  Ret;
  UINT64   TempRand;

  Ret = FALSE;

  if (RandBuffer == NULL) {
    DEBUG ((DEBUG_ERROR, "[OPENSSL_RAND_POOL] NULL RandBuffer. No random numbers are generated and your system is not secure\n"));
    ASSERT (RandBuffer != NULL); // Since we can't generate random numbers, we should assert. Otherwise we will just blow up later.
    return Ret;
  }

  while (Length > 0) {
    // Use RngLib to get random number
    Ret = GetRandomNumber64 (&TempRand);

    if (!Ret) {
      return Ret;
    }

    if (Length >= sizeof (TempRand)) {
      *((UINT64 *)RandBuffer) = TempRand;
      RandBuffer             += sizeof (UINT64);
      Length                 -= sizeof (TempRand);
    } else {
      CopyMem (RandBuffer, &TempRand, Length);
      Length = 0;
    }
  }

  return Ret;
}

/*
 * Add random bytes to the pool to acquire requested amount of entropy
 *
 * This function is platform specific and tries to acquire the requested
 * amount of entropy by polling platform specific entropy sources.
 *
 * This is OpenSSL required interface.
 */
size_t
ossl_pool_acquire_entropy (
  RAND_POOL  *pool
  )
{
  BOOLEAN        Ret;
  size_t         Bytes_needed;
  unsigned char  *Buffer;

  Bytes_needed = ossl_rand_pool_bytes_needed (pool, 1 /*entropy_factor*/);
  if (Bytes_needed > 0) {
    Buffer = ossl_rand_pool_add_begin (pool, Bytes_needed);

    if (Buffer != NULL) {
      Ret = RandGetBytes (Bytes_needed, Buffer);
      if (FALSE == Ret) {
        ossl_rand_pool_add_end (pool, 0, 0);
      } else {
        ossl_rand_pool_add_end (pool, Bytes_needed, 8 * Bytes_needed);
      }
    }
  }

  return ossl_rand_pool_entropy_available (pool);
}

/*
 * Implementation for UEFI
 *
 * This is OpenSSL required interface.
 */
int
ossl_pool_add_nonce_data (
  RAND_POOL  *pool
  )
{
  UINT8  data[16];

  RandGetBytes (sizeof (data), data);

  return ossl_rand_pool_add (pool, (unsigned char *)&data, sizeof (data), 0);
}

/*
 * Implementation for UEFI
 *
 * This is OpenSSL required interface.
 */
int
rand_pool_add_additional_data (
  RAND_POOL  *pool
  )
{
  UINT8  data[16];

  RandGetBytes (sizeof (data), data);

  return ossl_rand_pool_add (pool, (unsigned char *)&data, sizeof (data), 0);
}

/*
 * Dummy Implementation for UEFI
 *
 * This is OpenSSL required interface.
 */
int
ossl_rand_pool_init (
  VOID
  )
{
  return 1;
}

/*
 * Dummy Implementation for UEFI
 *
 * This is OpenSSL required interface.
 */
VOID
ossl_rand_pool_cleanup (
  VOID
  )
{
}

/*
 * Dummy Implementation for UEFI
 *
 * This is OpenSSL required interface.
 */
VOID
ossl_rand_pool_keep_random_devices_open (
  int  keep
  )
{
}