diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-06-10 19:02:22 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-06-10 19:02:22 +0000 |
commit | c1ef94962889276bdb3da2dd6aabbf445baa02b9 (patch) | |
tree | 6cfb5e13f7e1a6cc888781af89499544b2f294f7 | |
parent | d4aa6f7a81f9694cb9f07986c30e6372f71e3c08 (diff) | |
parent | b123d9c6910631856f78c2965ad5878b3d1e027c (diff) | |
download | android-c1ef94962889276bdb3da2dd6aabbf445baa02b9.tar.gz |
Snap for 4832339 from b123d9c6910631856f78c2965ad5878b3d1e027c to pi-releaseandroid-wear-9.0.0_r9android-wear-9.0.0_r8android-wear-9.0.0_r7android-wear-9.0.0_r6android-wear-9.0.0_r5android-wear-9.0.0_r4android-wear-9.0.0_r34android-wear-9.0.0_r33android-wear-9.0.0_r32android-wear-9.0.0_r31android-wear-9.0.0_r30android-wear-9.0.0_r3android-wear-9.0.0_r29android-wear-9.0.0_r28android-wear-9.0.0_r27android-wear-9.0.0_r26android-wear-9.0.0_r25android-wear-9.0.0_r24android-wear-9.0.0_r23android-wear-9.0.0_r22android-wear-9.0.0_r21android-wear-9.0.0_r20android-wear-9.0.0_r2android-wear-9.0.0_r19android-wear-9.0.0_r18android-wear-9.0.0_r17android-wear-9.0.0_r16android-wear-9.0.0_r15android-wear-9.0.0_r14android-wear-9.0.0_r13android-wear-9.0.0_r12android-wear-9.0.0_r11android-wear-9.0.0_r10android-wear-9.0.0_r1android-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r19android-vts-9.0_r18android-vts-9.0_r17android-vts-9.0_r16android-vts-9.0_r15android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r20android-cts-9.0_r2android-cts-9.0_r19android-cts-9.0_r18android-cts-9.0_r17android-cts-9.0_r16android-cts-9.0_r15android-cts-9.0_r14android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r6android-9.0.0_r5android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1pie-vts-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-cts-release
Change-Id: Ibac67393b189b0d1229a4f4afa1cb47e9e995008
-rw-r--r-- | citadel/citadeld/NOTICE | 177 | ||||
-rw-r--r-- | hals/NOTICE | 177 | ||||
-rw-r--r-- | hals/authsecret/AuthSecret.cpp | 10 | ||||
-rw-r--r-- | hals/keymaster/Android.bp | 1 | ||||
-rw-r--r-- | hals/keymaster/KeymasterDevice.cpp | 246 | ||||
-rw-r--r-- | hals/keymaster/buffer.cpp | 195 | ||||
-rw-r--r-- | hals/keymaster/buffer.h | 49 | ||||
-rw-r--r-- | hals/keymaster/proto_utils.cpp | 4 | ||||
-rw-r--r-- | hals/keymaster/proto_utils.h | 3 |
9 files changed, 813 insertions, 49 deletions
diff --git a/citadel/citadeld/NOTICE b/citadel/citadeld/NOTICE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/citadel/citadeld/NOTICE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/hals/NOTICE b/hals/NOTICE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/hals/NOTICE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/hals/authsecret/AuthSecret.cpp b/hals/authsecret/AuthSecret.cpp index 01ea99d..0f4bb66 100644 --- a/hals/authsecret/AuthSecret.cpp +++ b/hals/authsecret/AuthSecret.cpp @@ -128,7 +128,7 @@ void TryEnablingCitadelUpdate(NuggetClientInterface& client, const nugget_app_pa msg->which_headers = NUGGET_ENABLE_HEADER_RW | NUGGET_ENABLE_HEADER_RO; const uint32_t appStatus = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_ENABLE_UPDATE, - buffer, nullptr); + buffer, &buffer); if (appStatus == APP_ERROR_BOGUS_ARGS) { LOG(ERROR) << "Incorrect Citadel update password"; return; @@ -139,8 +139,12 @@ void TryEnablingCitadelUpdate(NuggetClientInterface& client, const nugget_app_pa return; } - // Reboot for the update to take effect - RebootCitadel(client); + // If the header[s] changed, reboot for the update to take effect + // Old firmware doesn't have a reply but still needs to be updated + if (buffer.empty() || buffer[0]) { + LOG(INFO) << "Update password enabled a new image; rebooting Citadel"; + RebootCitadel(client); + } } } // namespace diff --git a/hals/keymaster/Android.bp b/hals/keymaster/Android.bp index d730504..865fdeb 100644 --- a/hals/keymaster/Android.bp +++ b/hals/keymaster/Android.bp @@ -17,6 +17,7 @@ cc_library { name: "android.hardware.keymaster@4.0-impl.nos", srcs: [ + "buffer.cpp", "export_key.cpp", "import_key.cpp", "import_wrapped_key.cpp", diff --git a/hals/keymaster/KeymasterDevice.cpp b/hals/keymaster/KeymasterDevice.cpp index ee5c7d4..e56590d 100644 --- a/hals/keymaster/KeymasterDevice.cpp +++ b/hals/keymaster/KeymasterDevice.cpp @@ -15,6 +15,7 @@ */ #include "KeymasterDevice.h" +#include "buffer.h" #include "export_key.h" #include "import_key.h" #include "import_wrapped_key.h" @@ -49,6 +50,48 @@ std::string DigitsOnly(const std::string& code) { return filtered_code; } +/** Get one version number from a string and move loc to the point after the + * next version delimiter. + */ +uint32_t ExtractVersion(const std::string& version, size_t* loc) { + if (*loc == std::string::npos || *loc >= version.size()) { + return 0; + } + + uint32_t value = 0; + size_t new_loc = version.find('.', *loc); + if (new_loc == std::string::npos) { + auto sanitized = DigitsOnly(version.substr(*loc)); + if (!sanitized.empty()) { + if (sanitized.size() < version.size() - *loc) { + LOG(ERROR) << "Unexpected version format: \"" << version + << "\""; + } + value = std::stoi(sanitized); + } + *loc = new_loc; + } else { + auto sanitized = DigitsOnly(version.substr(*loc, new_loc - *loc)); + if (!sanitized.empty()) { + if (sanitized.size() < new_loc - *loc) { + LOG(ERROR) << "Unexpected version format: \"" << version + << "\""; + } + value = std::stoi(sanitized); + } + *loc = new_loc + 1; + } + return value; +} + +uint32_t VersionToUint32(const std::string& version) { + size_t loc = 0; + uint32_t major = ExtractVersion(version, &loc); + uint32_t minor = ExtractVersion(version, &loc); + uint32_t subminor = ExtractVersion(version, &loc); + return major * 10000 + minor * 100 + subminor; +} + uint32_t DateCodeToUint32(const std::string& code, bool include_day) { // Keep digits only. std::string filtered_code = DigitsOnly(code); @@ -65,6 +108,8 @@ uint32_t DateCodeToUint32(const std::string& code, bool include_day) { if (include_day) { return_value *= 100; } + } else { + LOG(ERROR) << "Unexpected patchset format: \"" << code << "\""; } return return_value; } @@ -104,8 +149,12 @@ using ::nugget::app::keymaster::ImportKeyRequest; using ::nugget::app::keymaster::ImportKeyResponse; using ::nugget::app::keymaster::ExportKeyRequest; using ::nugget::app::keymaster::ExportKeyResponse; -using ::nugget::app::keymaster::AttestKeyRequest; -using ::nugget::app::keymaster::AttestKeyResponse; +using ::nugget::app::keymaster::StartAttestKeyRequest; +using ::nugget::app::keymaster::StartAttestKeyResponse; +using ::nugget::app::keymaster::ContinueAttestKeyRequest; +using ::nugget::app::keymaster::ContinueAttestKeyResponse; +using ::nugget::app::keymaster::FinishAttestKeyRequest; +using ::nugget::app::keymaster::FinishAttestKeyResponse; using ::nugget::app::keymaster::UpgradeKeyRequest; using ::nugget::app::keymaster::UpgradeKeyResponse; using ::nugget::app::keymaster::DeleteKeyRequest; @@ -160,7 +209,7 @@ static ErrorCode status_to_error_code(uint32_t status) } } -#define KM_CALL(meth) { \ +#define KM_CALL(meth, request, response) { \ const uint32_t status = _keymaster. meth (request, &response); \ const ErrorCode error_code = translate_error_code(response.error_code()); \ if (status != APP_SUCCESS) { \ @@ -175,7 +224,7 @@ static ErrorCode status_to_error_code(uint32_t status) } \ } -#define KM_CALLV(meth, ...) { \ +#define KM_CALLV(meth, request, response, ...) { \ const uint32_t status = _keymaster. meth (request, &response); \ const ErrorCode error_code = translate_error_code(response.error_code()); \ if (status != APP_SUCCESS) { \ @@ -196,7 +245,7 @@ static ErrorCode status_to_error_code(uint32_t status) KeymasterDevice::KeymasterDevice(KeymasterClient& keymaster) : _keymaster{keymaster} { - _os_version = std::stoi(DigitsOnly(GetProperty(PROPERTY_OS_VERSION, ""))); + _os_version = VersionToUint32(GetProperty(PROPERTY_OS_VERSION, "")); _os_patchlevel = DateCodeToUint32(GetProperty(PROPERTY_OS_PATCHLEVEL, ""), false /* include_day */); _vendor_patchlevel = DateCodeToUint32( @@ -228,7 +277,7 @@ Return<void> KeymasterDevice::getHmacSharingParameters( GetHmacSharingParametersResponse response; HmacSharingParameters result; - KM_CALLV(GetHmacSharingParameters, result); + KM_CALLV(GetHmacSharingParameters, request, response, result); ErrorCode ec = translate_error_code(response.error_code()); @@ -286,7 +335,7 @@ Return<void> KeymasterDevice::computeSharedHmac( param.seed.size()); } - KM_CALLV(ComputeSharedHmac, result); + KM_CALLV(ComputeSharedHmac, request, response, result); ErrorCode ec = translate_error_code(response.error_code()); @@ -334,7 +383,7 @@ Return<ErrorCode> KeymasterDevice::addRngEntropy(const hidl_vec<uint8_t>& data) request.set_data(&data[i], std::min(chunk_size, data.size() - i)); // Call device. - KM_CALL(AddRngEntropy); + KM_CALL(AddRngEntropy, request, response); } return ErrorCode::OK; @@ -358,7 +407,8 @@ Return<void> KeymasterDevice::generateKey( } // Call device. - KM_CALLV(GenerateKey, hidl_vec<uint8_t>{}, KeyCharacteristics()); + KM_CALLV(GenerateKey, request, response, + hidl_vec<uint8_t>{}, KeyCharacteristics()); blob.setToExternal( reinterpret_cast<uint8_t*>( @@ -390,7 +440,7 @@ Return<void> KeymasterDevice::getKeyCharacteristics( request.set_app_data(&appData[0], appData.size()); // Call device. - KM_CALLV(GetKeyCharacteristics, KeyCharacteristics()); + KM_CALLV(GetKeyCharacteristics, request, response, KeyCharacteristics()); KeyCharacteristics characteristics; pb_to_hidl_params(response.characteristics().software_enforced(), @@ -420,7 +470,8 @@ Return<void> KeymasterDevice::importKey( return Void(); } - KM_CALLV(ImportKey, hidl_vec<uint8_t>{}, KeyCharacteristics{}); + KM_CALLV(ImportKey, request, response, + hidl_vec<uint8_t>{}, KeyCharacteristics{}); hidl_vec<uint8_t> blob; blob.setToExternal( @@ -459,7 +510,7 @@ Return<void> KeymasterDevice::exportKey( request.set_client_id(&clientId[0], clientId.size()); request.set_app_data(&appData[0], appData.size()); - KM_CALLV(ExportKey, hidl_vec<uint8_t>{}); + KM_CALLV(ExportKey, request, response, hidl_vec<uint8_t>{}); ErrorCode error_code = translate_error_code(response.error_code()); if (error_code != ErrorCode::OK) { @@ -480,32 +531,63 @@ Return<void> KeymasterDevice::attestKey( { LOG(VERBOSE) << "Running KeymasterDevice::attestKey"; - AttestKeyRequest request; - AttestKeyResponse response; + StartAttestKeyRequest startRequest; + StartAttestKeyResponse startResponse; - request.mutable_blob()->set_blob(&keyToAttest[0], keyToAttest.size()); + startRequest.mutable_blob()->set_blob(&keyToAttest[0], keyToAttest.size()); vector<hidl_vec<uint8_t> > chain; if (hidl_params_to_pb( - attestParams, request.mutable_params()) != ErrorCode::OK) { + attestParams, startRequest.mutable_params()) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, chain); return Void(); } - KM_CALLV(AttestKey, hidl_vec<hidl_vec<uint8_t> >{}); + // TODO: + // startRequest.set_attestation_app_id_len( + // attestation_app_id_len(attestParams)); - for (int i = 0; i < response.chain().certificates_size(); i++) { - hidl_vec<uint8_t> blob; - blob.setToExternal( - reinterpret_cast<uint8_t*>( - const_cast<char*>( - response.chain().certificates(i).data().data())), - response.chain().certificates(i).data().size(), false); - chain.push_back(blob); - } + KM_CALLV(StartAttestKey, startRequest, startResponse, + hidl_vec<hidl_vec<uint8_t> >{}); - _hidl_cb(translate_error_code(response.error_code()), - hidl_vec<hidl_vec<uint8_t> >(chain)); + uint64_t operationHandle = startResponse.handle().handle(); + ContinueAttestKeyRequest continueRequest; + ContinueAttestKeyResponse continueResponse; + + continueRequest.mutable_handle()->set_handle(operationHandle); + // TODO + // continueRequest.set_attestation_app_id( + // attestation_app_id(attestParams)); + + KM_CALLV(ContinueAttestKey, continueRequest, continueResponse, + hidl_vec<hidl_vec<uint8_t> >{}); + + FinishAttestKeyRequest finishRequest; + FinishAttestKeyResponse finishResponse; + + finishRequest.mutable_handle()->set_handle(operationHandle); + + KM_CALLV(FinishAttestKey, finishRequest, finishResponse, + hidl_vec<hidl_vec<uint8_t> >{}); + + std::stringstream ss; + ss << startResponse.certificate_prologue(); + ss << continueResponse.certificate_body(); + ss << finishResponse.certificate_epilogue(); + + hidl_vec<uint8_t> attestation_certificate; + attestation_certificate.setToExternal( + reinterpret_cast<uint8_t*>( + const_cast<char*>(ss.str().data())), + ss.str().size(), false); + + chain.push_back(attestation_certificate); + // TODO: + // chain.push_back(intermediate_certificate()); + // chain.push_back(root_certificate()); + // verify cert chain + + _hidl_cb(ErrorCode::OK, hidl_vec<hidl_vec<uint8_t> >(chain)); return Void(); } @@ -529,7 +611,7 @@ Return<void> KeymasterDevice::upgradeKey( return Void(); } - KM_CALLV(UpgradeKey, hidl_vec<uint8_t>{}); + KM_CALLV(UpgradeKey, request, response, hidl_vec<uint8_t>{}); blob.setToExternal( reinterpret_cast<uint8_t*>( @@ -549,7 +631,7 @@ Return<ErrorCode> KeymasterDevice::deleteKey(const hidl_vec<uint8_t>& keyBlob) request.mutable_blob()->set_blob(&keyBlob[0], keyBlob.size()); - KM_CALL(DeleteKey); + KM_CALL(DeleteKey, request, response); return translate_error_code(response.error_code()); } @@ -561,7 +643,7 @@ Return<ErrorCode> KeymasterDevice::deleteAllKeys() DeleteAllKeysRequest request; DeleteAllKeysResponse response; - KM_CALL(DeleteAllKeys); + KM_CALL(DeleteAllKeys, request, response); return translate_error_code(response.error_code()); } @@ -573,7 +655,7 @@ Return<ErrorCode> KeymasterDevice::destroyAttestationIds() DestroyAttestationIdsRequest request; DestroyAttestationIdsResponse response; - KM_CALL(DestroyAttestationIds); + KM_CALL(DestroyAttestationIds, request, response); return translate_error_code(response.error_code()); } @@ -593,6 +675,7 @@ Return<void> KeymasterDevice::begin( request.mutable_blob()->set_blob(&key[0], key.size()); hidl_vec<KeyParameter> params; + tag_map_t tag_map; if (translate_auth_token( authToken, request.mutable_auth_token()) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, params, @@ -605,8 +688,36 @@ Return<void> KeymasterDevice::begin( response.handle().handle()); return Void(); } + if (hidl_params_to_map(inParams, &tag_map) != ErrorCode::OK) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, params, + response.handle().handle()); + return Void(); + } - KM_CALLV(BeginOperation, hidl_vec<KeyParameter>{}, 0); + KM_CALLV(BeginOperation, request, response, hidl_vec<KeyParameter>{}, 0); + + // Setup HAL buffering for this operation's data. + Algorithm algorithm; + if (translate_algorithm(response.algorithm(), &algorithm) != + ErrorCode::OK) { + if (this->abort(response.handle().handle()) != ErrorCode::OK) { + LOG(ERROR) << "abort( " << response.handle().handle() + << ") failed"; + } + _hidl_cb(ErrorCode::INVALID_ARGUMENT, params, + response.handle().handle()); + return Void(); + } + ErrorCode error_code = buffer_begin(response.handle().handle(), algorithm); + if (error_code != ErrorCode::OK) { + if (this->abort(response.handle().handle()) != ErrorCode::OK) { + LOG(ERROR) << "abort( " << response.handle().handle() + << ") failed"; + } + _hidl_cb(ErrorCode::UNKNOWN_ERROR, params, + response.handle().handle()); + return Void(); + } pb_to_hidl_params(response.params(), ¶ms); @@ -628,6 +739,7 @@ Return<void> KeymasterDevice::update( UpdateOperationRequest request; UpdateOperationResponse response; + // TODO: does keystore chunk stream data? To what quantum? if (input.size() > KM_MAX_PROTO_FIELD_SIZE) { LOG(ERROR) << "Excess input length: " << input.size() << "max allowed: " << KM_MAX_PROTO_FIELD_SIZE; @@ -640,17 +752,38 @@ Return<void> KeymasterDevice::update( return Void(); } + uint32_t consumed; + hidl_vec<uint8_t> output; + hidl_vec<KeyParameter> params; + ErrorCode error_code; + error_code = buffer_append(operationHandle, input, &consumed); + if (error_code != ErrorCode::OK) { + _hidl_cb(error_code, 0, params, output); + return Void(); + } + + hidl_vec<uint8_t> blocks; + error_code = buffer_peek(operationHandle, &blocks); + if (error_code != ErrorCode::OK) { + _hidl_cb(error_code, 0, params, output); + return Void(); + } + + if (blocks.size() == 0) { + // Insufficient data available to proceed. + _hidl_cb(ErrorCode::OK, consumed, params, output); + return Void(); + } + request.mutable_handle()->set_handle(operationHandle); - hidl_vec<KeyParameter> params; - hidl_vec<uint8_t> output; if (hidl_params_to_pb( inParams, request.mutable_params()) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, 0, params, output); return Void(); } - request.set_input(&input[0], input.size()); + request.set_input(&blocks[0], blocks.size()); if (translate_auth_token( authToken, request.mutable_auth_token()) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, 0, params, output); @@ -659,14 +792,20 @@ Return<void> KeymasterDevice::update( translate_verification_token(verificationToken, request.mutable_verification_token()); - KM_CALLV(UpdateOperation, 0, hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); + KM_CALLV(UpdateOperation, request, response, + 0, hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); + + if (buffer_advance(operationHandle, response.consumed()) != ErrorCode::OK) { + _hidl_cb(ErrorCode::UNKNOWN_ERROR, 0, params, output); + return Void(); + } pb_to_hidl_params(response.params(), ¶ms); output.setToExternal( reinterpret_cast<uint8_t*>(const_cast<char*>(response.output().data())), response.output().size(), false); - _hidl_cb(ErrorCode::OK, response.consumed(), params, output); + _hidl_cb(ErrorCode::OK, consumed, params, output); return Void(); } @@ -696,6 +835,23 @@ Return<void> KeymasterDevice::finish( return Void(); } + uint32_t consumed; + ErrorCode error_code; + error_code = buffer_append(operationHandle, input, &consumed); + if (error_code != ErrorCode::OK) { + _hidl_cb(error_code, + hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); + return Void(); + } + + hidl_vec<uint8_t> data; + error_code = buffer_final(operationHandle, &data); + if (error_code != ErrorCode::OK) { + _hidl_cb(error_code, + hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); + return Void(); + } + request.mutable_handle()->set_handle(operationHandle); hidl_vec<KeyParameter> params; @@ -706,7 +862,7 @@ Return<void> KeymasterDevice::finish( return Void(); } - request.set_input(&input[0], input.size()); + request.set_input(&data[0], data.size()); request.set_signature(&signature[0], signature.size()); if (translate_auth_token( @@ -717,7 +873,8 @@ Return<void> KeymasterDevice::finish( translate_verification_token(verificationToken, request.mutable_verification_token()); - KM_CALLV(FinishOperation, hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); + KM_CALLV(FinishOperation, request, response, + hidl_vec<KeyParameter>{}, hidl_vec<uint8_t>{}); pb_to_hidl_params(response.params(), ¶ms); output.setToExternal( @@ -737,7 +894,7 @@ Return<ErrorCode> KeymasterDevice::abort(uint64_t operationHandle) request.mutable_handle()->set_handle(operationHandle); - KM_CALL(AbortOperation); + KM_CALL(AbortOperation, request, response); return ErrorCode::OK; } @@ -772,7 +929,8 @@ Return<void> KeymasterDevice::importWrappedKey( return Void(); } - KM_CALLV(ImportWrappedKey, hidl_vec<uint8_t>{}, KeyCharacteristics{}); + KM_CALLV(ImportWrappedKey, request, response, + hidl_vec<uint8_t>{}, KeyCharacteristics{}); hidl_vec<uint8_t> blob; blob.setToExternal( @@ -807,7 +965,7 @@ Return<ErrorCode> KeymasterDevice::SendSystemVersionInfo() const { request.set_system_security_level(_os_patchlevel); request.set_vendor_security_level(_vendor_patchlevel); - KM_CALL(SetSystemVersionInfo); + KM_CALL(SetSystemVersionInfo, request, response); return ErrorCode::OK; } @@ -815,7 +973,7 @@ Return<ErrorCode> KeymasterDevice::GetBootInfo() { GetBootInfoRequest request; GetBootInfoResponse response; - KM_CALL(GetBootInfo); + KM_CALL(GetBootInfo, request, response); _is_unlocked = response.is_unlocked(); _boot_color = response.boot_color(); diff --git a/hals/keymaster/buffer.cpp b/hals/keymaster/buffer.cpp new file mode 100644 index 0000000..05e9c3e --- /dev/null +++ b/hals/keymaster/buffer.cpp @@ -0,0 +1,195 @@ +/* + * Copyright 2018 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 "buffer.h" +#include "proto_utils.h" + +#include <keymasterV4_0/key_param_output.h> + +#include <android-base/logging.h> + +#include <openssl/rsa.h> + +#include <map> +#include <vector> + +namespace android { +namespace hardware { +namespace keymaster { + +// HAL +using ::android::hardware::keymaster::V4_0::Algorithm; +using ::android::hardware::keymaster::V4_0::ErrorCode; + +// std +using std::map; +using std::pair; +using std::vector; + +static const size_t kMaxChunkSize = 256; + +class Operation { +public: + Operation(Algorithm algorithm) : _algorithm(algorithm), _buffer{} { + switch (_algorithm) { + case Algorithm::AES: + _blockSize = 16; + break; + case Algorithm::TRIPLE_DES: + _blockSize = 8; + break; + case Algorithm::RSA: + case Algorithm::EC: + case Algorithm::HMAC: + _blockSize = 0; + default: + break; + } + } + + size_t remaining() const { + return _buffer.size(); + } + + void append(const hidl_vec<uint8_t>& input, uint32_t *consumed) { + _buffer.insert(_buffer.end(), input.begin(), input.end()); + *consumed = input.size(); + } + + void peek(hidl_vec<uint8_t> *data) { + // Retain at least one full block; this is done so that when + // either GCM mode or PKCS7 padding are in use, the last block + // will be available to be consumed by final(). + if (_buffer.size() <= _blockSize) { + *data = vector<uint8_t>(); + return; + } + + size_t retain; + if (_blockSize == 0) { + retain = 0; + } else { + retain = (_buffer.size() % _blockSize) + _blockSize; + } + const size_t count = std::min(_buffer.size() - retain, kMaxChunkSize); + *data = vector<uint8_t>(_buffer.begin(), _buffer.begin() + count); + } + + ErrorCode advance(size_t count) { + if (count > _buffer.size()) { + LOG(ERROR) << "Attempt to advance " << count + << " bytes, where occupancy is " << _buffer.size(); + return ErrorCode::UNKNOWN_ERROR; + } + _buffer.erase(_buffer.begin(), _buffer.begin() + count); + return ErrorCode::OK; + } + + void final(hidl_vec<uint8_t> *data) { + if (data != NULL) { + *data = _buffer; + } + _buffer.clear(); + } + +private: + Algorithm _algorithm; + size_t _blockSize; + vector<uint8_t> _buffer; +}; + +static map<uint64_t, Operation> buffer_map; +typedef map<uint64_t, Operation>::iterator buffer_item; + +ErrorCode buffer_begin(uint64_t handle, Algorithm algorithm) +{ + if (buffer_map.find(handle) != buffer_map.end()) { + LOG(ERROR) << "Duplicate operation handle " << handle + << "returned by begin()"; + // Final the existing op to potential mishandling of data. + buffer_final(handle, NULL); + return ErrorCode::UNKNOWN_ERROR; + } + + buffer_map.insert( + pair<uint64_t, Operation>(handle, Operation(algorithm))); + return ErrorCode::OK; +} + +size_t buffer_remaining(uint64_t handle) { + if (buffer_map.find(handle) == buffer_map.end()) { + LOG(ERROR) << "Remaining requested on absent operation: " << handle; + return 0; + } + + const Operation &op = buffer_map.find(handle)->second; + return op.remaining(); +} + +ErrorCode buffer_append(uint64_t handle, + const hidl_vec<uint8_t>& input, + uint32_t *consumed) +{ + if (buffer_map.find(handle) == buffer_map.end()) { + LOG(ERROR) << "Append requested on absent operation: " << handle; + return ErrorCode::UNKNOWN_ERROR; + } + + Operation *op = &buffer_map.find(handle)->second; + op->append(input, consumed); + return ErrorCode::OK; +} + +ErrorCode buffer_peek(uint64_t handle, + hidl_vec<uint8_t> *data) +{ + if (buffer_map.find(handle) == buffer_map.end()) { + LOG(ERROR) << "Read requested on absent operation: " << handle; + return ErrorCode::UNKNOWN_ERROR; + } + + Operation *op = &buffer_map.find(handle)->second; + op->peek(data); + return ErrorCode::OK; +} + +ErrorCode buffer_advance(uint64_t handle, size_t count) +{ + if (buffer_map.find(handle) == buffer_map.end()) { + LOG(ERROR) << "Read requested on absent operation: " << handle; + return ErrorCode::UNKNOWN_ERROR; + } + + Operation *op = &buffer_map.find(handle)->second; + return op->advance(count); +} + +ErrorCode buffer_final(uint64_t handle, + hidl_vec<uint8_t> *data) +{ + if (buffer_map.find(handle) == buffer_map.end()) { + LOG(ERROR) << "Final requested on absent operation: " << handle; + return ErrorCode::UNKNOWN_ERROR; + } + Operation *op = &buffer_map.find(handle)->second; + op->final(data); + buffer_map.erase(handle); + return ErrorCode::OK; +} + +} // namespace keymaster +} // hardware +} // android diff --git a/hals/keymaster/buffer.h b/hals/keymaster/buffer.h new file mode 100644 index 0000000..a4a23e3 --- /dev/null +++ b/hals/keymaster/buffer.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018 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. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_BUFFER_H +#define ANDROID_HARDWARE_KEYMASTER_BUFFER_H + +#include <android/hardware/keymaster/4.0/IKeymasterDevice.h> + +#include <Keymaster.client.h> + +using ::nugget::app::keymaster::BeginOperationResponse; + +namespace android { +namespace hardware { +namespace keymaster { + +// HAL +using ::android::hardware::keymaster::V4_0::Algorithm; +using ::android::hardware::keymaster::V4_0::ErrorCode; + +size_t buffer_remaining(uint64_t handle); +ErrorCode buffer_begin(uint64_t handle, Algorithm algorithm); +ErrorCode buffer_append(uint64_t handle, + const hidl_vec<uint8_t>& input, + uint32_t *consumed); +ErrorCode buffer_peek(uint64_t handle, + hidl_vec<uint8_t> *data); +ErrorCode buffer_advance(uint64_t handle, size_t count); +ErrorCode buffer_final(uint64_t handle, + hidl_vec<uint8_t> *data); + +} // namespace keymaster +} // hardware +} // android + +#endif // ANDROID_HARDWARE_KEYMASTER_IMPORT_KEY_H diff --git a/hals/keymaster/proto_utils.cpp b/hals/keymaster/proto_utils.cpp index d3cb753..c27b76b 100644 --- a/hals/keymaster/proto_utils.cpp +++ b/hals/keymaster/proto_utils.cpp @@ -127,8 +127,8 @@ static nosapp::Algorithm translate_algorithm(Algorithm algorithm) } } -static ErrorCode translate_algorithm(nosapp::Algorithm algorithm, - Algorithm *out) +ErrorCode translate_algorithm(nosapp::Algorithm algorithm, + Algorithm *out) { switch (algorithm) { case nosapp::Algorithm::RSA: diff --git a/hals/keymaster/proto_utils.h b/hals/keymaster/proto_utils.h index b1d0f41..a59eab3 100644 --- a/hals/keymaster/proto_utils.h +++ b/hals/keymaster/proto_utils.h @@ -29,6 +29,7 @@ namespace hardware { namespace keymaster { // HAL +using ::android::hardware::keymaster::V4_0::Algorithm; using ::android::hardware::keymaster::V4_0::EcCurve; using ::android::hardware::keymaster::V4_0::ErrorCode; using ::android::hardware::keymaster::V4_0::HardwareAuthToken; @@ -57,6 +58,8 @@ ErrorCode map_params_to_pb(const tag_map_t& params, nosapp::KeyParameters *pbParams); ErrorCode pb_to_hidl_params(const nosapp::KeyParameters& pbParams, hidl_vec<KeyParameter> *params); +ErrorCode translate_algorithm(nosapp::Algorithm algorithm, + Algorithm *out); ErrorCode translate_error_code(nosapp::ErrorCode error_code); ErrorCode translate_ec_curve(nosapp::EcCurve ec_curve, EcCurve *out); ErrorCode translate_auth_token(const HardwareAuthToken& auth_token, |