xref: /aosp_15_r20/system/keymaster/android_keymaster/operation.cpp (revision 789431f29546679ab5188a97751fb38e3018d44d)
1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
3*789431f2SAndroid Build Coastguard Worker  *
4*789431f2SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*789431f2SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*789431f2SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*789431f2SAndroid Build Coastguard Worker  *
8*789431f2SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*789431f2SAndroid Build Coastguard Worker  *
10*789431f2SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*789431f2SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*789431f2SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*789431f2SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*789431f2SAndroid Build Coastguard Worker  * limitations under the License.
15*789431f2SAndroid Build Coastguard Worker  */
16*789431f2SAndroid Build Coastguard Worker 
17*789431f2SAndroid Build Coastguard Worker #include <keymaster/authorization_set.h>
18*789431f2SAndroid Build Coastguard Worker #include <keymaster/key.h>
19*789431f2SAndroid Build Coastguard Worker #include <keymaster/operation.h>
20*789431f2SAndroid Build Coastguard Worker 
21*789431f2SAndroid Build Coastguard Worker namespace keymaster {
22*789431f2SAndroid Build Coastguard Worker 
supported(keymaster_padding_t padding) const23*789431f2SAndroid Build Coastguard Worker bool OperationFactory::supported(keymaster_padding_t padding) const {
24*789431f2SAndroid Build Coastguard Worker     size_t padding_count;
25*789431f2SAndroid Build Coastguard Worker     const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
26*789431f2SAndroid Build Coastguard Worker     for (size_t i = 0; i < padding_count; ++i)
27*789431f2SAndroid Build Coastguard Worker         if (padding == supported_paddings[i]) return true;
28*789431f2SAndroid Build Coastguard Worker     return false;
29*789431f2SAndroid Build Coastguard Worker }
30*789431f2SAndroid Build Coastguard Worker 
supported(keymaster_block_mode_t block_mode) const31*789431f2SAndroid Build Coastguard Worker bool OperationFactory::supported(keymaster_block_mode_t block_mode) const {
32*789431f2SAndroid Build Coastguard Worker     size_t block_mode_count;
33*789431f2SAndroid Build Coastguard Worker     const keymaster_block_mode_t* supported_block_modes = SupportedBlockModes(&block_mode_count);
34*789431f2SAndroid Build Coastguard Worker     for (size_t i = 0; i < block_mode_count; ++i)
35*789431f2SAndroid Build Coastguard Worker         if (block_mode == supported_block_modes[i]) return true;
36*789431f2SAndroid Build Coastguard Worker     return false;
37*789431f2SAndroid Build Coastguard Worker }
38*789431f2SAndroid Build Coastguard Worker 
supported(keymaster_digest_t digest) const39*789431f2SAndroid Build Coastguard Worker bool OperationFactory::supported(keymaster_digest_t digest) const {
40*789431f2SAndroid Build Coastguard Worker     size_t digest_count;
41*789431f2SAndroid Build Coastguard Worker     const keymaster_digest_t* supported_digests = SupportedDigests(&digest_count);
42*789431f2SAndroid Build Coastguard Worker     for (size_t i = 0; i < digest_count; ++i)
43*789431f2SAndroid Build Coastguard Worker         if (digest == supported_digests[i]) return true;
44*789431f2SAndroid Build Coastguard Worker     return false;
45*789431f2SAndroid Build Coastguard Worker }
46*789431f2SAndroid Build Coastguard Worker 
is_public_key_algorithm(keymaster_algorithm_t algorithm)47*789431f2SAndroid Build Coastguard Worker inline bool is_public_key_algorithm(keymaster_algorithm_t algorithm) {
48*789431f2SAndroid Build Coastguard Worker     switch (algorithm) {
49*789431f2SAndroid Build Coastguard Worker     case KM_ALGORITHM_HMAC:
50*789431f2SAndroid Build Coastguard Worker     case KM_ALGORITHM_AES:
51*789431f2SAndroid Build Coastguard Worker     case KM_ALGORITHM_TRIPLE_DES:
52*789431f2SAndroid Build Coastguard Worker         return false;
53*789431f2SAndroid Build Coastguard Worker     case KM_ALGORITHM_RSA:
54*789431f2SAndroid Build Coastguard Worker     case KM_ALGORITHM_EC:
55*789431f2SAndroid Build Coastguard Worker         return true;
56*789431f2SAndroid Build Coastguard Worker     }
57*789431f2SAndroid Build Coastguard Worker 
58*789431f2SAndroid Build Coastguard Worker     // Unreachable.
59*789431f2SAndroid Build Coastguard Worker     assert(false);
60*789431f2SAndroid Build Coastguard Worker     return false;
61*789431f2SAndroid Build Coastguard Worker }
62*789431f2SAndroid Build Coastguard Worker 
is_public_key_operation() const63*789431f2SAndroid Build Coastguard Worker bool OperationFactory::is_public_key_operation() const {
64*789431f2SAndroid Build Coastguard Worker     KeyType key_type = registry_key();
65*789431f2SAndroid Build Coastguard Worker 
66*789431f2SAndroid Build Coastguard Worker     if (!is_public_key_algorithm(key_type.algorithm)) return false;
67*789431f2SAndroid Build Coastguard Worker 
68*789431f2SAndroid Build Coastguard Worker     switch (key_type.purpose) {
69*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_VERIFY:
70*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_ENCRYPT:
71*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_WRAP:
72*789431f2SAndroid Build Coastguard Worker         return true;
73*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_SIGN:
74*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_DECRYPT:
75*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_DERIVE_KEY:
76*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_AGREE_KEY:
77*789431f2SAndroid Build Coastguard Worker     case KM_PURPOSE_ATTEST_KEY:
78*789431f2SAndroid Build Coastguard Worker         return false;
79*789431f2SAndroid Build Coastguard Worker     };
80*789431f2SAndroid Build Coastguard Worker 
81*789431f2SAndroid Build Coastguard Worker     // Unreachable.
82*789431f2SAndroid Build Coastguard Worker     assert(false);
83*789431f2SAndroid Build Coastguard Worker     return false;
84*789431f2SAndroid Build Coastguard Worker }
85*789431f2SAndroid Build Coastguard Worker 
GetAndValidatePadding(const AuthorizationSet & begin_params,const Key & key,keymaster_padding_t * padding,keymaster_error_t * error) const86*789431f2SAndroid Build Coastguard Worker bool OperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
87*789431f2SAndroid Build Coastguard Worker                                              keymaster_padding_t* padding,
88*789431f2SAndroid Build Coastguard Worker                                              keymaster_error_t* error) const {
89*789431f2SAndroid Build Coastguard Worker     *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
90*789431f2SAndroid Build Coastguard Worker     if (!begin_params.GetTagValue(TAG_PADDING, padding)) {
91*789431f2SAndroid Build Coastguard Worker         LOG_E("%zu padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
92*789431f2SAndroid Build Coastguard Worker         return false;
93*789431f2SAndroid Build Coastguard Worker     } else if (!supported(*padding)) {
94*789431f2SAndroid Build Coastguard Worker         LOG_E("Padding mode %d not supported", *padding);
95*789431f2SAndroid Build Coastguard Worker         return false;
96*789431f2SAndroid Build Coastguard Worker     } else if (
97*789431f2SAndroid Build Coastguard Worker         // If it's a public key operation, all padding modes are authorized.
98*789431f2SAndroid Build Coastguard Worker         !is_public_key_operation() &&
99*789431f2SAndroid Build Coastguard Worker         // Otherwise the key needs to authorize the specific mode.
100*789431f2SAndroid Build Coastguard Worker         !key.authorizations().Contains(TAG_PADDING, *padding) &&
101*789431f2SAndroid Build Coastguard Worker         !key.authorizations().Contains(TAG_PADDING_OLD, *padding)) {
102*789431f2SAndroid Build Coastguard Worker         LOG_E("Padding mode %d was specified, but not authorized by key", *padding);
103*789431f2SAndroid Build Coastguard Worker         *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
104*789431f2SAndroid Build Coastguard Worker         return false;
105*789431f2SAndroid Build Coastguard Worker     }
106*789431f2SAndroid Build Coastguard Worker 
107*789431f2SAndroid Build Coastguard Worker     *error = KM_ERROR_OK;
108*789431f2SAndroid Build Coastguard Worker     return true;
109*789431f2SAndroid Build Coastguard Worker }
110*789431f2SAndroid Build Coastguard Worker 
GetAndValidateDigest(const AuthorizationSet & begin_params,const Key & key,keymaster_digest_t * digest,keymaster_error_t * error) const111*789431f2SAndroid Build Coastguard Worker bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
112*789431f2SAndroid Build Coastguard Worker                                             keymaster_digest_t* digest,
113*789431f2SAndroid Build Coastguard Worker                                             keymaster_error_t* error) const {
114*789431f2SAndroid Build Coastguard Worker     return GetAndValidateDigest(begin_params, key, digest, error, false);
115*789431f2SAndroid Build Coastguard Worker }
116*789431f2SAndroid Build Coastguard Worker 
GetAndValidateDigest(const AuthorizationSet & begin_params,const Key & key,keymaster_digest_t * digest,keymaster_error_t * error,bool require_explicit_digest) const117*789431f2SAndroid Build Coastguard Worker bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
118*789431f2SAndroid Build Coastguard Worker                                             keymaster_digest_t* digest, keymaster_error_t* error,
119*789431f2SAndroid Build Coastguard Worker                                             bool require_explicit_digest) const {
120*789431f2SAndroid Build Coastguard Worker     *error = KM_ERROR_UNSUPPORTED_DIGEST;
121*789431f2SAndroid Build Coastguard Worker     if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
122*789431f2SAndroid Build Coastguard Worker         if (require_explicit_digest) {
123*789431f2SAndroid Build Coastguard Worker             return false;
124*789431f2SAndroid Build Coastguard Worker         }
125*789431f2SAndroid Build Coastguard Worker         if (key.authorizations().Contains(TAG_DIGEST, KM_DIGEST_NONE)) {
126*789431f2SAndroid Build Coastguard Worker             *digest = KM_DIGEST_NONE;
127*789431f2SAndroid Build Coastguard Worker         } else {
128*789431f2SAndroid Build Coastguard Worker             LOG_E("%zu digests specified in begin params and NONE not authorized",
129*789431f2SAndroid Build Coastguard Worker                   begin_params.GetTagCount(TAG_DIGEST));
130*789431f2SAndroid Build Coastguard Worker             return false;
131*789431f2SAndroid Build Coastguard Worker         }
132*789431f2SAndroid Build Coastguard Worker     } else if (!supported(*digest)) {
133*789431f2SAndroid Build Coastguard Worker         LOG_E("Digest %d not supported", *digest);
134*789431f2SAndroid Build Coastguard Worker         return false;
135*789431f2SAndroid Build Coastguard Worker     } else if (
136*789431f2SAndroid Build Coastguard Worker         // If it's a public key operation, all digests are authorized.
137*789431f2SAndroid Build Coastguard Worker         !is_public_key_operation() &&
138*789431f2SAndroid Build Coastguard Worker         // Otherwise the key needs to authorize the specific digest.
139*789431f2SAndroid Build Coastguard Worker         !key.authorizations().Contains(TAG_DIGEST, *digest) &&
140*789431f2SAndroid Build Coastguard Worker         !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
141*789431f2SAndroid Build Coastguard Worker         LOG_E("Digest %d was specified, but not authorized by key", *digest);
142*789431f2SAndroid Build Coastguard Worker         *error = KM_ERROR_INCOMPATIBLE_DIGEST;
143*789431f2SAndroid Build Coastguard Worker         return false;
144*789431f2SAndroid Build Coastguard Worker     }
145*789431f2SAndroid Build Coastguard Worker     *error = KM_ERROR_OK;
146*789431f2SAndroid Build Coastguard Worker     return true;
147*789431f2SAndroid Build Coastguard Worker }
148*789431f2SAndroid Build Coastguard Worker 
UpdateForFinish(const AuthorizationSet & input_params,const Buffer & input)149*789431f2SAndroid Build Coastguard Worker keymaster_error_t Operation::UpdateForFinish(const AuthorizationSet& input_params,
150*789431f2SAndroid Build Coastguard Worker                                              const Buffer& input) {
151*789431f2SAndroid Build Coastguard Worker     if (!input_params.empty() || input.available_read()) {
152*789431f2SAndroid Build Coastguard Worker         size_t input_consumed;
153*789431f2SAndroid Build Coastguard Worker         Buffer output;
154*789431f2SAndroid Build Coastguard Worker         AuthorizationSet output_params;
155*789431f2SAndroid Build Coastguard Worker         keymaster_error_t error =
156*789431f2SAndroid Build Coastguard Worker             Update(input_params, input, &output_params, &output, &input_consumed);
157*789431f2SAndroid Build Coastguard Worker         if (error != KM_ERROR_OK) return error;
158*789431f2SAndroid Build Coastguard Worker         assert(input_consumed == input.available_read());
159*789431f2SAndroid Build Coastguard Worker         assert(output_params.empty());
160*789431f2SAndroid Build Coastguard Worker         assert(output.available_read() == 0);
161*789431f2SAndroid Build Coastguard Worker     }
162*789431f2SAndroid Build Coastguard Worker 
163*789431f2SAndroid Build Coastguard Worker     return KM_ERROR_OK;
164*789431f2SAndroid Build Coastguard Worker }
165*789431f2SAndroid Build Coastguard Worker 
166*789431f2SAndroid Build Coastguard Worker }  // namespace keymaster
167