operation.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright 2014 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 <keymaster/authorization_set.h>
  17. #include <keymaster/key.h>
  18. #include <keymaster/operation.h>
  19. namespace keymaster {
  20. bool OperationFactory::supported(keymaster_padding_t padding) const {
  21. size_t padding_count;
  22. const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
  23. for (size_t i = 0; i < padding_count; ++i)
  24. if (padding == supported_paddings[i])
  25. return true;
  26. return false;
  27. }
  28. bool OperationFactory::supported(keymaster_block_mode_t block_mode) const {
  29. size_t block_mode_count;
  30. const keymaster_block_mode_t* supported_block_modes = SupportedBlockModes(&block_mode_count);
  31. for (size_t i = 0; i < block_mode_count; ++i)
  32. if (block_mode == supported_block_modes[i])
  33. return true;
  34. return false;
  35. }
  36. bool OperationFactory::supported(keymaster_digest_t digest) const {
  37. size_t digest_count;
  38. const keymaster_digest_t* supported_digests = SupportedDigests(&digest_count);
  39. for (size_t i = 0; i < digest_count; ++i)
  40. if (digest == supported_digests[i])
  41. return true;
  42. return false;
  43. }
  44. inline bool is_public_key_algorithm(keymaster_algorithm_t algorithm) {
  45. switch (algorithm) {
  46. case KM_ALGORITHM_HMAC:
  47. case KM_ALGORITHM_AES:
  48. case KM_ALGORITHM_TRIPLE_DES:
  49. return false;
  50. case KM_ALGORITHM_RSA:
  51. case KM_ALGORITHM_EC:
  52. return true;
  53. }
  54. // Unreachable.
  55. assert(false);
  56. return false;
  57. }
  58. bool OperationFactory::is_public_key_operation() const {
  59. KeyType key_type = registry_key();
  60. if (!is_public_key_algorithm(key_type.algorithm))
  61. return false;
  62. switch (key_type.purpose) {
  63. case KM_PURPOSE_VERIFY:
  64. case KM_PURPOSE_ENCRYPT:
  65. case KM_PURPOSE_WRAP:
  66. return true;
  67. case KM_PURPOSE_SIGN:
  68. case KM_PURPOSE_DECRYPT:
  69. case KM_PURPOSE_DERIVE_KEY:
  70. return false;
  71. };
  72. // Unreachable.
  73. assert(false);
  74. return false;
  75. }
  76. bool OperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
  77. keymaster_padding_t* padding,
  78. keymaster_error_t* error) const {
  79. *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
  80. if (!begin_params.GetTagValue(TAG_PADDING, padding)) {
  81. LOG_E("%d padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
  82. return false;
  83. } else if (!supported(*padding)) {
  84. LOG_E("Padding mode %d not supported", *padding);
  85. return false;
  86. } else if (
  87. // If it's a public key operation, all padding modes are authorized.
  88. !is_public_key_operation() &&
  89. // Otherwise the key needs to authorize the specific mode.
  90. !key.authorizations().Contains(TAG_PADDING, *padding) &&
  91. !key.authorizations().Contains(TAG_PADDING_OLD, *padding)) {
  92. LOG_E("Padding mode %d was specified, but not authorized by key", *padding);
  93. *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
  94. return false;
  95. }
  96. *error = KM_ERROR_OK;
  97. return true;
  98. }
  99. bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
  100. keymaster_digest_t* digest,
  101. keymaster_error_t* error) const {
  102. *error = KM_ERROR_UNSUPPORTED_DIGEST;
  103. if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
  104. if (key.authorizations().Contains(TAG_DIGEST, KM_DIGEST_NONE)) {
  105. *digest = KM_DIGEST_NONE;
  106. } else {
  107. LOG_E("%d digests specified in begin params and NONE not authorized",
  108. begin_params.GetTagCount(TAG_DIGEST));
  109. return false;
  110. }
  111. } else if (!supported(*digest)) {
  112. LOG_E("Digest %d not supported", *digest);
  113. return false;
  114. } else if (
  115. // If it's a public key operation, all digests are authorized.
  116. !is_public_key_operation() &&
  117. // Otherwise the key needs to authorize the specific digest.
  118. !key.authorizations().Contains(TAG_DIGEST, *digest) &&
  119. !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
  120. LOG_E("Digest %d was specified, but not authorized by key", *digest);
  121. *error = KM_ERROR_INCOMPATIBLE_DIGEST;
  122. return false;
  123. }
  124. *error = KM_ERROR_OK;
  125. return true;
  126. }
  127. keymaster_error_t Operation::UpdateForFinish(const AuthorizationSet& input_params,
  128. const Buffer& input) {
  129. if (!input_params.empty() || input.available_read()) {
  130. size_t input_consumed;
  131. Buffer output;
  132. AuthorizationSet output_params;
  133. keymaster_error_t error =
  134. Update(input_params, input, &output_params, &output, &input_consumed);
  135. if (error != KM_ERROR_OK)
  136. return error;
  137. assert(input_consumed == input.available_read());
  138. assert(output_params.empty());
  139. assert(output.available_read() == 0);
  140. }
  141. return KM_ERROR_OK;
  142. }
  143. } // namespace keymaster