blob: de030a0386c84db8082fed39e1e5e850baa9ebde [file] [log] [blame]
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "operation.h"
#include <keymaster/authorization_set.h>
#include "key.h"
namespace keymaster {
bool OperationFactory::supported(keymaster_padding_t padding) const {
size_t padding_count;
const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
for (size_t i = 0; i < padding_count; ++i)
if (padding == supported_paddings[i])
return true;
return false;
}
bool OperationFactory::supported(keymaster_block_mode_t block_mode) const {
size_t block_mode_count;
const keymaster_block_mode_t* supported_block_modes = SupportedBlockModes(&block_mode_count);
for (size_t i = 0; i < block_mode_count; ++i)
if (block_mode == supported_block_modes[i])
return true;
return false;
}
bool OperationFactory::supported(keymaster_digest_t digest) const {
size_t digest_count;
const keymaster_digest_t* supported_digests = SupportedDigests(&digest_count);
for (size_t i = 0; i < digest_count; ++i)
if (digest == supported_digests[i])
return true;
return false;
}
bool OperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
keymaster_padding_t* padding,
keymaster_error_t* error) const {
*error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
if (!begin_params.GetTagValue(TAG_PADDING, padding)) {
LOG_E("%d padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
return false;
} else if (!supported(*padding)) {
LOG_E("Padding mode %d not supported", *padding);
return false;
} else if (
// If key contains KM_PAD_NONE, all padding modes are authorized.
!key.authorizations().Contains(TAG_PADDING, KM_PAD_NONE) &&
!key.authorizations().Contains(TAG_PADDING_OLD, KM_PAD_NONE) &&
// Otherwise the key needs to authorize the specific mode.
!key.authorizations().Contains(TAG_PADDING, *padding) &&
!key.authorizations().Contains(TAG_PADDING_OLD, *padding)) {
LOG_E("Padding mode %d was specified, but not authorized by key", *padding);
*error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
return false;
}
*error = KM_ERROR_OK;
return true;
}
bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
keymaster_digest_t* digest,
keymaster_error_t* error) const {
*error = KM_ERROR_UNSUPPORTED_DIGEST;
if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
LOG_E("%d digests specified in begin params", begin_params.GetTagCount(TAG_DIGEST));
return false;
} else if (!supported(*digest)) {
LOG_E("Digest %d not supported", *digest);
return false;
} else if (
// If key contains KM_DIGEST_NONE, all digests are authorized.
!key.authorizations().Contains(TAG_DIGEST, KM_DIGEST_NONE) &&
!key.authorizations().Contains(TAG_DIGEST_OLD, KM_DIGEST_NONE) &&
// Otherwise the key needs to authorize the specific digest.
!key.authorizations().Contains(TAG_DIGEST, *digest) &&
!key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
LOG_E("Digest %d was specified, but not authorized by key", *digest);
*error = KM_ERROR_INCOMPATIBLE_DIGEST;
return false;
}
*error = KM_ERROR_OK;
return true;
}
} // namespace keymaster