• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include "tpm_random_source.h"
17 
18 #include <android-base/logging.h>
19 #include "tss2/tss2_esys.h"
20 #include "tss2/tss2_rc.h"
21 
22 namespace cuttlefish {
23 
TpmRandomSource(ESYS_CONTEXT * esys)24 TpmRandomSource::TpmRandomSource(ESYS_CONTEXT* esys) : esys_(esys) {
25 }
26 
GenerateRandom(uint8_t * random,size_t requested_length) const27 keymaster_error_t TpmRandomSource::GenerateRandom(
28     uint8_t* random, size_t requested_length) const {
29   if (requested_length == 0) {
30     return KM_ERROR_OK;
31   }
32   // TODO(b/158790549): Pipeline these calls.
33   TPM2B_DIGEST* generated = nullptr;
34   while (requested_length > sizeof(generated->buffer)) {
35     auto rc = Esys_GetRandom(esys_, ESYS_TR_NONE, ESYS_TR_NONE,
36                              ESYS_TR_NONE, sizeof(generated->buffer),
37                              &generated);
38     if (rc != TSS2_RC_SUCCESS) {
39       LOG(ERROR) << "Esys_GetRandom failed with " << rc << " ("
40                  << Tss2_RC_Decode(rc) << ")";
41       // TODO(b/158790404): Return a better error code.
42       return KM_ERROR_UNKNOWN_ERROR;
43     }
44     memcpy(random, generated->buffer, sizeof(generated->buffer));
45     random = (uint8_t*) random + sizeof(generated->buffer);
46     requested_length -= sizeof(generated->buffer);
47     Esys_Free(generated);
48   }
49   auto rc = Esys_GetRandom(esys_, ESYS_TR_NONE, ESYS_TR_NONE,
50                            ESYS_TR_NONE, requested_length, &generated);
51   if (rc != TSS2_RC_SUCCESS) {
52     LOG(ERROR) << "Esys_GetRandom failed with " << rc << " ("
53                 << Tss2_RC_Decode(rc) << ")";
54     // TODO(b/158790404): Return a better error code.
55     return KM_ERROR_UNKNOWN_ERROR;
56   }
57   memcpy(random, generated->buffer, requested_length);
58   Esys_Free(generated);
59   return KM_ERROR_OK;
60 }
61 
62 // From TPM2_StirRandom specification.
63 static int MAX_STIR_RANDOM_BUFFER_SIZE = 128;
64 
AddRngEntropy(const uint8_t * buffer,size_t size) const65 keymaster_error_t TpmRandomSource::AddRngEntropy(
66     const uint8_t* buffer, size_t size) const {
67   if (size > 2048) {
68     // IKeyMintDevice.aidl specifies that there's an upper limit of 2KiB.
69     return KM_ERROR_INVALID_INPUT_LENGTH;
70   }
71 
72   TPM2B_SENSITIVE_DATA in_data;
73   while (size > MAX_STIR_RANDOM_BUFFER_SIZE) {
74     memcpy(in_data.buffer, buffer, MAX_STIR_RANDOM_BUFFER_SIZE);
75     in_data.size = MAX_STIR_RANDOM_BUFFER_SIZE;
76     buffer += MAX_STIR_RANDOM_BUFFER_SIZE;
77     size -= MAX_STIR_RANDOM_BUFFER_SIZE;
78     auto rc = Esys_StirRandom(
79         esys_,
80         ESYS_TR_NONE,
81         ESYS_TR_NONE,
82         ESYS_TR_NONE,
83         &in_data);
84     if (rc != TSS2_RC_SUCCESS) {
85       LOG(ERROR) << "Esys_StirRandom failed with " << rc << "("
86                  << Tss2_RC_Decode(rc) << ")";
87       return KM_ERROR_UNKNOWN_ERROR;
88     }
89   }
90   if (size == 0) {
91     return KM_ERROR_OK;
92   }
93   memcpy(in_data.buffer, buffer, size);
94   auto rc = Esys_StirRandom(
95       esys_,
96       ESYS_TR_NONE,
97       ESYS_TR_NONE,
98       ESYS_TR_NONE,
99       &in_data);
100   if (rc != TSS2_RC_SUCCESS) {
101     LOG(ERROR) << "Esys_StirRandom failed with " << rc << "("
102                 << Tss2_RC_Decode(rc) << ")";
103     return KM_ERROR_UNKNOWN_ERROR;
104   }
105   return KM_ERROR_OK;
106 }
107 
108 }  // namespace cuttlefish
109