blob: 175d8bb9abef3b40883c81b043af2ebbb3a4780b [file] [log] [blame]
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +00001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! This module implements test utils to generate various types of keys.
16
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +000017use anyhow::Result;
18
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +000019use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Rajesh Nyamagoud11912ea2021-12-20 20:37:20 +000020 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
Rajesh Nyamagoudb8402b62022-04-08 01:05:47 +000021 ErrorCode::ErrorCode, KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
22 KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
23 Tag::Tag,
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +000024};
25use android_system_keystore2::aidl::android::system::keystore2::{
Rajesh Nyamagoudb8402b62022-04-08 01:05:47 +000026 Authorization::Authorization, Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
27 KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +000028};
29
30use crate::authorizations::AuthSetBuilder;
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +000031use android_system_keystore2::binder::{ExceptionCode, Result as BinderResult};
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +000032
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +000033/// Shell namespace.
34pub const SELINUX_SHELL_NAMESPACE: i64 = 1;
Rajesh Nyamagouddc6fb232021-12-08 21:27:15 +000035/// Vold namespace.
36pub const SELINUX_VOLD_NAMESPACE: i64 = 100;
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +000037
Rajesh Nyamagoudfa7c0f12021-12-02 17:15:48 +000038/// SU context.
39pub const TARGET_SU_CTX: &str = "u:r:su:s0";
40
41/// Vold context
42pub const TARGET_VOLD_CTX: &str = "u:r:vold:s0";
43
Rajesh Nyamagoud11912ea2021-12-20 20:37:20 +000044/// Key parameters to generate a key.
45pub struct KeyParams {
46 /// Key Size.
47 pub key_size: i32,
48 /// Key Purposes.
49 pub purpose: Vec<KeyPurpose>,
50 /// Padding Mode.
51 pub padding: Option<PaddingMode>,
52 /// Digest.
53 pub digest: Option<Digest>,
54 /// MFG Digest.
55 pub mgf_digest: Option<Digest>,
56 /// Block Mode.
57 pub block_mode: Option<BlockMode>,
58 /// Attestation challenge.
59 pub att_challenge: Option<Vec<u8>>,
60 /// Attestation app id.
61 pub att_app_id: Option<Vec<u8>>,
62}
63
Rajesh Nyamagoudb8402b62022-04-08 01:05:47 +000064/// DER-encoded PKCS#8 format RSA key. Generated using:
65/// openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
66pub static RSA_2048_KEY: &[u8] = &[
67 0x30, 0x82, 0x04, 0xBD, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
68 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xA7, 0x30, 0x82, 0x04, 0xA3, 0x02, 0x01,
69 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xE5, 0x14, 0xE3, 0xC2, 0x43, 0xF3, 0x0F, 0xCC, 0x22, 0x73,
70 0x9C, 0x84, 0xCC, 0x1B, 0x6C, 0x97, 0x4B, 0xC9, 0xDF, 0x1F, 0xE2, 0xB8, 0x80, 0x85, 0xF9, 0x27,
71 0xAB, 0x97, 0x94, 0x58, 0x4B, 0xC9, 0x40, 0x94, 0x5A, 0xB4, 0xD4, 0xF8, 0xD0, 0x36, 0xC4, 0x86,
72 0x17, 0x7D, 0xA2, 0x48, 0x6D, 0x40, 0xF0, 0xB9, 0x61, 0x4F, 0xCE, 0x65, 0x80, 0x88, 0x81, 0x59,
73 0x95, 0x11, 0x24, 0xF4, 0x36, 0xB7, 0xB7, 0x37, 0x44, 0xF4, 0x6C, 0x1C, 0xEB, 0x04, 0x19, 0x78,
74 0xB2, 0x29, 0x4D, 0x21, 0x44, 0x16, 0x57, 0x58, 0x6D, 0x7D, 0x56, 0xB5, 0x99, 0xDD, 0xD2, 0xAD,
75 0x02, 0x9A, 0x72, 0x16, 0x67, 0xD6, 0x00, 0x9F, 0x69, 0xE0, 0x25, 0xEE, 0x7C, 0x86, 0x54, 0x27,
76 0x4B, 0x50, 0xEF, 0x60, 0x52, 0x60, 0x82, 0xAA, 0x09, 0x15, 0x72, 0xD2, 0xEB, 0x01, 0x52, 0x04,
77 0x39, 0x60, 0xBC, 0x5E, 0x95, 0x07, 0xC8, 0xC2, 0x3A, 0x3A, 0xE2, 0xA4, 0x99, 0x6B, 0x27, 0xE3,
78 0xA3, 0x55, 0x69, 0xC4, 0xB3, 0x2D, 0x19, 0xC4, 0x34, 0x76, 0xFC, 0x27, 0xDA, 0x22, 0xB2, 0x62,
79 0x69, 0x25, 0xDE, 0x0D, 0xE7, 0x54, 0x3C, 0xBB, 0x61, 0xD2, 0x20, 0xDA, 0x7B, 0x6E, 0x63, 0xBD,
80 0x9A, 0x4B, 0xCD, 0x75, 0xC6, 0xA1, 0x5E, 0x1C, 0x3E, 0xD5, 0x63, 0x59, 0x22, 0x7E, 0xE0, 0x6C,
81 0x98, 0x25, 0x63, 0x97, 0x56, 0xDF, 0x71, 0xF5, 0x4C, 0x78, 0xE9, 0xE1, 0xD5, 0xFC, 0xF8, 0x5A,
82 0x5B, 0xF6, 0x1D, 0xFA, 0x5A, 0x99, 0x4C, 0x99, 0x19, 0x21, 0x1D, 0xF5, 0x24, 0x07, 0xEF, 0x8A,
83 0xC9, 0x9F, 0xE7, 0x3F, 0xBB, 0x46, 0x1A, 0x16, 0x96, 0xC6, 0xD6, 0x12, 0x7E, 0xDA, 0xCB, 0xEB,
84 0x2F, 0x1D, 0x3B, 0x31, 0xCC, 0x55, 0x63, 0xA2, 0x6F, 0x8A, 0xDE, 0x35, 0x52, 0x40, 0x04, 0xBF,
85 0xE0, 0x82, 0x32, 0xE1, 0x6D, 0x8B, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x2D,
86 0x1F, 0x71, 0x41, 0x79, 0xBA, 0xED, 0xD8, 0xAA, 0xCC, 0x94, 0xFE, 0xFF, 0x69, 0x43, 0x79, 0x85,
87 0xBF, 0x2C, 0xC9, 0x0E, 0x12, 0x83, 0x96, 0x60, 0x1E, 0x75, 0x49, 0x35, 0x3A, 0x33, 0x2B, 0x60,
88 0x22, 0x18, 0xBF, 0xD7, 0xD7, 0x6E, 0xC3, 0xEA, 0xEF, 0xF2, 0xBE, 0x97, 0x71, 0xA6, 0xBB, 0x8C,
89 0xEF, 0x27, 0x00, 0xDE, 0x49, 0xD6, 0x08, 0x8D, 0x5A, 0x04, 0xE7, 0xCC, 0x9C, 0xA2, 0x0E, 0x8B,
90 0xF3, 0x42, 0x0C, 0xD7, 0x22, 0xD7, 0x14, 0x06, 0xA4, 0x64, 0x8B, 0x88, 0x1A, 0xCE, 0x5B, 0x8C,
91 0x36, 0xE9, 0xD2, 0x2F, 0x7B, 0x33, 0xE4, 0xA2, 0xB3, 0xDB, 0x78, 0x6A, 0x92, 0x89, 0x3F, 0x78,
92 0xFD, 0xED, 0x8F, 0xEE, 0x48, 0xCC, 0x94, 0x75, 0x0D, 0x0C, 0x63, 0xD3, 0xD2, 0xE8, 0x47, 0x04,
93 0x55, 0xD3, 0xD6, 0x3A, 0xB8, 0xDA, 0xFB, 0x76, 0x99, 0x48, 0x68, 0x0A, 0x92, 0xA2, 0xCD, 0xF7,
94 0x45, 0x8B, 0x50, 0xFE, 0xF9, 0x1A, 0x33, 0x24, 0x3C, 0x2E, 0xDE, 0x88, 0xAD, 0xB2, 0x5B, 0x9F,
95 0x44, 0xEA, 0xD1, 0x9F, 0xC7, 0x9F, 0x02, 0x5E, 0x31, 0x61, 0xB3, 0xD6, 0xE2, 0xE1, 0xBC, 0xFB,
96 0x1C, 0xDB, 0xBD, 0xB2, 0x9A, 0xE5, 0xEF, 0xDA, 0xCD, 0x29, 0xA5, 0x45, 0xCC, 0x67, 0x01, 0x8B,
97 0x1C, 0x1D, 0x0E, 0x8F, 0x73, 0x69, 0x4D, 0x4D, 0xF6, 0x9D, 0xA6, 0x6C, 0x9A, 0x1C, 0xF4, 0x5C,
98 0xE4, 0x83, 0x9A, 0x77, 0x12, 0x01, 0xBD, 0xCE, 0x66, 0x3A, 0x4B, 0x3D, 0x6E, 0xE0, 0x6E, 0x82,
99 0x98, 0xDE, 0x74, 0x11, 0x47, 0xEC, 0x7A, 0x3A, 0xA9, 0xD8, 0x48, 0x00, 0x26, 0x64, 0x47, 0x7B,
100 0xAE, 0x55, 0x9D, 0x29, 0x22, 0xB4, 0xB3, 0xB9, 0xB1, 0x64, 0xEA, 0x3B, 0x5A, 0xD3, 0x3F, 0x8D,
101 0x0F, 0x14, 0x7E, 0x4E, 0xB8, 0x1B, 0x06, 0xFC, 0xB1, 0x7E, 0xCD, 0xB9, 0x1A, 0x4E, 0xA1, 0x02,
102 0x81, 0x81, 0x00, 0xF9, 0xDE, 0xEE, 0xED, 0x13, 0x2F, 0xBB, 0xE7, 0xE2, 0xB3, 0x2D, 0x98, 0xD2,
103 0xE8, 0x25, 0x07, 0x5A, 0x1E, 0x51, 0x0A, 0xC8, 0xAD, 0x50, 0x4B, 0x80, 0xC6, 0x22, 0xF5, 0x9B,
104 0x08, 0xE6, 0x3D, 0x01, 0xC6, 0x3E, 0xC8, 0xD2, 0x54, 0x9F, 0x91, 0x77, 0x95, 0xCD, 0xCA, 0xC7,
105 0xE7, 0x47, 0x94, 0xA9, 0x5F, 0x4E, 0xBE, 0x31, 0x3D, 0xB4, 0xAF, 0x43, 0x0F, 0xDC, 0x8D, 0x9C,
106 0x1E, 0x52, 0x7B, 0x72, 0x21, 0x34, 0xB3, 0x96, 0x7C, 0x9C, 0xB8, 0x51, 0x65, 0x60, 0xAC, 0x3D,
107 0x11, 0x32, 0xB8, 0xD6, 0x34, 0x35, 0x66, 0xD0, 0x30, 0xB9, 0xE9, 0x67, 0x2C, 0x87, 0x73, 0x43,
108 0x9C, 0x12, 0x16, 0x7D, 0x4A, 0xD9, 0xA3, 0x4C, 0x24, 0x64, 0x6A, 0x32, 0x8E, 0xC3, 0xD8, 0x00,
109 0x90, 0x5C, 0x4D, 0x65, 0x01, 0x53, 0x8A, 0xD0, 0x87, 0xCE, 0x96, 0xEF, 0xFA, 0x73, 0x03, 0xF1,
110 0xDC, 0x1B, 0x9B, 0x02, 0x81, 0x81, 0x00, 0xEA, 0xB3, 0x69, 0x00, 0x11, 0x0E, 0x50, 0xAA, 0xD3,
111 0x22, 0x51, 0x78, 0x9D, 0xFF, 0x05, 0x62, 0xBC, 0x9A, 0x67, 0x86, 0xE1, 0xC5, 0x02, 0x2D, 0x14,
112 0x11, 0x29, 0x30, 0xE7, 0x90, 0x5D, 0x72, 0x6F, 0xC5, 0x62, 0xEB, 0xD4, 0xB0, 0x3F, 0x3D, 0xDC,
113 0xB9, 0xFC, 0x2B, 0x5C, 0xBD, 0x9E, 0x71, 0x81, 0x5C, 0xC5, 0xFE, 0xDF, 0x69, 0x73, 0x12, 0x66,
114 0x92, 0x06, 0xD4, 0xD5, 0x8F, 0xDF, 0x14, 0x2E, 0x9C, 0xD0, 0x4C, 0xC2, 0x4D, 0x31, 0x2E, 0x47,
115 0xA5, 0xDC, 0x8A, 0x83, 0x7B, 0xE8, 0xA5, 0xC3, 0x03, 0x98, 0xD8, 0xBF, 0xF4, 0x7D, 0x6E, 0x87,
116 0x55, 0xE4, 0x0F, 0x15, 0x10, 0xC8, 0x76, 0x4F, 0xAD, 0x1D, 0x1C, 0x95, 0x41, 0x9D, 0x88, 0xEC,
117 0x8C, 0xDA, 0xBA, 0x90, 0x7F, 0x8D, 0xD9, 0x8B, 0x47, 0x6C, 0x0C, 0xFF, 0xBA, 0x73, 0x00, 0x20,
118 0x1F, 0xF7, 0x7E, 0x5F, 0xF4, 0xEC, 0xD1, 0x02, 0x81, 0x80, 0x16, 0xB7, 0x43, 0xB5, 0x5D, 0xD7,
119 0x2B, 0x18, 0x0B, 0xAE, 0x0A, 0x69, 0x28, 0x53, 0x5E, 0x7A, 0x6A, 0xA0, 0xF2, 0xF1, 0x2E, 0x09,
120 0x43, 0x91, 0x79, 0xA5, 0x89, 0xAC, 0x16, 0x6A, 0x1A, 0xB4, 0x55, 0x22, 0xF6, 0xB6, 0x3F, 0x18,
121 0xDE, 0x60, 0xD5, 0x24, 0x53, 0x4F, 0x2A, 0x19, 0x46, 0x92, 0xA7, 0x4B, 0x38, 0xD7, 0x65, 0x96,
122 0x9C, 0x84, 0x8A, 0x6E, 0x38, 0xB8, 0xCF, 0x06, 0x9A, 0xAD, 0x0A, 0x55, 0x26, 0x7B, 0x65, 0x24,
123 0xF3, 0x02, 0x76, 0xB3, 0xE6, 0xB4, 0x01, 0xE1, 0x3C, 0x61, 0x3D, 0x68, 0x05, 0xAA, 0xD1, 0x26,
124 0x7C, 0xE0, 0x51, 0x36, 0xE5, 0x21, 0x7F, 0x76, 0x02, 0xD6, 0xF4, 0x91, 0x07, 0x74, 0x27, 0x09,
125 0xEF, 0xEF, 0x0F, 0xA5, 0x96, 0xFC, 0x5E, 0x20, 0xC1, 0xA3, 0x6F, 0x99, 0x4D, 0x45, 0x03, 0x6C,
126 0x35, 0x45, 0xD7, 0x8F, 0x47, 0x41, 0x86, 0x8D, 0x62, 0x1D, 0x02, 0x81, 0x81, 0x00, 0xC3, 0x93,
127 0x85, 0xA7, 0xFC, 0x8E, 0x85, 0x42, 0x14, 0x76, 0xC0, 0x95, 0x56, 0x73, 0xB0, 0xB5, 0x3A, 0x9D,
128 0x20, 0x30, 0x11, 0xEA, 0xED, 0x89, 0x4A, 0xF3, 0x91, 0xF3, 0xA2, 0xC3, 0x76, 0x5B, 0x6A, 0x30,
129 0x7D, 0xE2, 0x2F, 0x76, 0x3E, 0xFC, 0xF9, 0xF6, 0x31, 0xE0, 0xA0, 0x83, 0x92, 0x88, 0xDB, 0x57,
130 0xC7, 0xD6, 0x3F, 0xAD, 0xCB, 0xAA, 0x45, 0xB6, 0xE1, 0xE2, 0x71, 0xA4, 0x56, 0x2C, 0xA7, 0x3B,
131 0x1D, 0x89, 0x19, 0x50, 0xE1, 0xEE, 0xC2, 0xDD, 0xC0, 0x0D, 0xDC, 0xCB, 0x60, 0x6E, 0xE1, 0x37,
132 0x1A, 0x23, 0x64, 0xB2, 0x03, 0xE4, 0x1A, 0xFA, 0xC3, 0xF4, 0x9D, 0x85, 0x42, 0xC6, 0xF4, 0x56,
133 0x39, 0xB0, 0x1B, 0xE0, 0x75, 0xBA, 0x28, 0x04, 0xA8, 0x30, 0x57, 0x41, 0x33, 0x9F, 0x58, 0xA4,
134 0xC7, 0xB1, 0x7D, 0x58, 0x8D, 0x84, 0x49, 0x40, 0xDA, 0x28, 0x81, 0x25, 0xC4, 0x41, 0x02, 0x81,
135 0x80, 0x13, 0x20, 0x65, 0xD5, 0x96, 0x98, 0x8D, 0x16, 0x73, 0xA1, 0x31, 0x73, 0x79, 0xBA, 0xEC,
136 0xB0, 0xD9, 0x0C, 0xF6, 0xEF, 0x2F, 0xC2, 0xE7, 0x96, 0x9B, 0xA1, 0x2D, 0xE9, 0xFB, 0x45, 0xB9,
137 0xD0, 0x30, 0xE2, 0xBD, 0x30, 0x4F, 0xB6, 0xFE, 0x24, 0x02, 0xCF, 0x8D, 0x51, 0x48, 0x45, 0xD9,
138 0xF7, 0x20, 0x53, 0x1C, 0x0B, 0xA9, 0x7E, 0xC2, 0xA2, 0x65, 0xCC, 0x3E, 0x0E, 0x0D, 0xF1, 0x62,
139 0xDD, 0x5F, 0xBC, 0x55, 0x9B, 0x58, 0x26, 0x40, 0x6A, 0xEE, 0x02, 0x55, 0x36, 0xE9, 0xBA, 0x82,
140 0x5A, 0xFD, 0x3C, 0xDF, 0xA6, 0x26, 0x32, 0x81, 0xA9, 0x5E, 0x46, 0xBE, 0xBA, 0xDC, 0xD3, 0x2A,
141 0x3A, 0x3B, 0xC1, 0x4E, 0xF7, 0x1A, 0xDC, 0x4B, 0xAF, 0x67, 0x1B, 0x3A, 0x83, 0x0D, 0x04, 0xDE,
142 0x27, 0x47, 0xFC, 0xE6, 0x39, 0x89, 0x7B, 0x66, 0xF9, 0x50, 0x4D, 0xF1, 0xAC, 0x20, 0x43, 0x7E,
143 0xEE,
144];
145
146/// DER-encoded PKCS#8 format EC key. Generated using:
147/// openssl ecparam -name prime256v1 -genkey | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
148pub static EC_P_256_KEY: &[u8] = &[
149 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
150 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02,
151 0x01, 0x01, 0x04, 0x20, 0xB9, 0x1D, 0xAF, 0x50, 0xFD, 0xD8, 0x6A, 0x40, 0xAB, 0x2C, 0xCB, 0x54,
152 0x4E, 0xED, 0xF1, 0x64, 0xBC, 0x30, 0x25, 0xFB, 0xC4, 0x69, 0x00, 0x34, 0x1A, 0x82, 0xA3, 0x72,
153 0x5D, 0xC7, 0xA9, 0x85, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xE8, 0x53, 0x0A, 0xF2, 0xD3, 0x68,
154 0x40, 0x48, 0x8C, 0xB4, 0x2F, 0x11, 0x34, 0xD7, 0xF4, 0x4A, 0x5C, 0x33, 0xFF, 0xF6, 0x2B, 0xF7,
155 0x98, 0x0F, 0x02, 0xA5, 0xD7, 0x4F, 0xF9, 0xDE, 0x60, 0x9C, 0x6E, 0xB0, 0x45, 0xDA, 0x3F, 0xF4,
156 0x34, 0x23, 0x9B, 0x4C, 0x3A, 0x09, 0x9C, 0x5E, 0x5D, 0x37, 0x96, 0xAC, 0x4A, 0xE7, 0x65, 0x2B,
157 0xD6, 0x84, 0x98, 0xEA, 0x96, 0x91, 0xFB, 0x78, 0xED, 0x86,
158];
159
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000160/// To map Keystore errors.
161#[derive(thiserror::Error, Debug, Eq, PartialEq)]
162pub enum Error {
163 /// Keystore2 error code
164 #[error("ResponseCode {0:?}")]
165 Rc(ResponseCode),
166 /// Keymint error code
167 #[error("ErrorCode {0:?}")]
168 Km(ErrorCode),
169 /// Exception
170 #[error("Binder exception {0:?}")]
171 Binder(ExceptionCode),
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +0000172 /// This is returned if the C implementation of extractSubjectFromCertificate failed.
173 #[error("Failed to validate certificate chain.")]
174 ValidateCertChainFailed,
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000175}
176
177/// Keystore2 error mapping.
178pub fn map_ks_error<T>(r: BinderResult<T>) -> Result<T, Error> {
179 r.map_err(|s| {
180 match s.exception_code() {
181 ExceptionCode::SERVICE_SPECIFIC => {
182 match s.service_specific_error() {
183 se if se < 0 => {
184 // Negative service specific errors are KM error codes.
185 Error::Km(ErrorCode(se))
186 }
187 se => {
188 // Positive service specific errors are KS response codes.
189 Error::Rc(ResponseCode(se))
190 }
191 }
192 }
193 // We create `Error::Binder` to preserve the exception code
194 // for logging.
195 e_code => Error::Binder(e_code),
196 }
197 })
198}
199
200/// Generate EC Key using given security level and domain with below key parameters and
201/// optionally allow the generated key to be attested with factory provisioned attest key using
202/// given challenge and application id -
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000203/// Purposes: SIGN and VERIFY
204/// Digest: SHA_2_256
205/// Curve: P_256
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000206pub fn generate_ec_p256_signing_key(
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000207 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000208 domain: Domain,
209 nspace: i64,
210 alias: Option<String>,
211 att_challenge: Option<&[u8]>,
212 att_app_id: Option<&[u8]>,
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000213) -> binder::Result<KeyMetadata> {
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000214 let mut key_attest = false;
215 let mut gen_params = AuthSetBuilder::new()
Rajesh Nyamagoudc7d064d2022-08-20 01:45:17 +0000216 .no_auth_required()
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000217 .algorithm(Algorithm::EC)
218 .purpose(KeyPurpose::SIGN)
219 .purpose(KeyPurpose::VERIFY)
220 .digest(Digest::SHA_2_256)
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000221 .ec_curve(EcCurve::P_256);
222
223 if let Some(challenge) = att_challenge {
224 key_attest = true;
225 gen_params = gen_params.clone().attestation_challenge(challenge.to_vec());
226 }
227
228 if let Some(app_id) = att_app_id {
229 key_attest = true;
230 gen_params = gen_params.clone().attestation_app_id(app_id.to_vec());
231 }
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000232
233 match sec_level.generateKey(
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000234 &KeyDescriptor { domain, nspace, alias, blob: None },
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000235 None,
236 &gen_params,
237 0,
238 b"entropy",
239 ) {
240 Ok(key_metadata) => {
241 assert!(key_metadata.certificate.is_some());
Rajesh Nyamagoudb881d512021-12-10 00:33:15 +0000242 if key_attest {
243 assert!(key_metadata.certificateChain.is_some());
244 }
245 if domain == Domain::BLOB {
246 assert!(key_metadata.key.blob.is_some());
247 }
Rajesh Nyamagoud901386c2022-03-21 20:35:18 +0000248
249 Ok(key_metadata)
250 }
251 Err(e) => Err(e),
252 }
253}
Rajesh Nyamagouda7766452021-12-13 21:44:19 +0000254
255/// Generate EC signing key.
Rajesh Nyamagoudc7d064d2022-08-20 01:45:17 +0000256pub fn generate_ec_key(
257 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
Rajesh Nyamagouda7766452021-12-13 21:44:19 +0000258 domain: Domain,
259 nspace: i64,
260 alias: Option<String>,
261 ec_curve: EcCurve,
262 digest: Digest,
263) -> binder::Result<KeyMetadata> {
264 let gen_params = AuthSetBuilder::new()
265 .no_auth_required()
266 .algorithm(Algorithm::EC)
267 .purpose(KeyPurpose::SIGN)
268 .purpose(KeyPurpose::VERIFY)
269 .digest(digest)
270 .ec_curve(ec_curve);
271
272 let key_metadata = sec_level.generateKey(
273 &KeyDescriptor { domain, nspace, alias, blob: None },
274 None,
275 &gen_params,
276 0,
277 b"entropy",
278 )?;
279
280 // Must have a public key.
281 assert!(key_metadata.certificate.is_some());
282
283 // Should not have an attestation record.
284 assert!(key_metadata.certificateChain.is_none());
285
286 if domain == Domain::BLOB {
287 assert!(key_metadata.key.blob.is_some());
288 } else {
289 assert!(key_metadata.key.blob.is_none());
290 }
291 Ok(key_metadata)
292}
Rajesh Nyamagoud11912ea2021-12-20 20:37:20 +0000293
294/// Generate a RSA key with the given key parameters, alias, domain and namespace.
295pub fn generate_rsa_key(
296 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
297 domain: Domain,
298 nspace: i64,
299 alias: Option<String>,
300 key_params: &KeyParams,
301 attest_key: Option<&KeyDescriptor>,
302) -> binder::Result<KeyMetadata> {
303 let mut gen_params = AuthSetBuilder::new()
304 .no_auth_required()
305 .algorithm(Algorithm::RSA)
306 .rsa_public_exponent(65537)
307 .key_size(key_params.key_size);
308
309 for purpose in &key_params.purpose {
310 gen_params = gen_params.purpose(*purpose);
311 }
312 if let Some(value) = key_params.digest {
313 gen_params = gen_params.digest(value)
314 }
315 if let Some(value) = key_params.padding {
316 gen_params = gen_params.padding_mode(value);
317 }
318 if let Some(value) = key_params.mgf_digest {
319 gen_params = gen_params.mgf_digest(value);
320 }
321 if let Some(value) = key_params.block_mode {
322 gen_params = gen_params.block_mode(value)
323 }
324 if let Some(value) = &key_params.att_challenge {
325 gen_params = gen_params.attestation_challenge(value.to_vec())
326 }
327 if let Some(value) = &key_params.att_app_id {
328 gen_params = gen_params.attestation_app_id(value.to_vec())
329 }
330
331 let key_metadata = sec_level.generateKey(
332 &KeyDescriptor { domain, nspace, alias, blob: None },
333 attest_key,
334 &gen_params,
335 0,
336 b"entropy",
337 )?;
338
339 // Must have a public key.
340 assert!(key_metadata.certificate.is_some());
341
342 if attest_key.is_none() && key_params.att_challenge.is_some() && key_params.att_app_id.is_some()
343 {
344 // Should have an attestation record.
345 assert!(key_metadata.certificateChain.is_some());
346 } else {
347 // Should not have an attestation record.
348 assert!(key_metadata.certificateChain.is_none());
349 }
350
351 assert!(
352 (domain == Domain::BLOB && key_metadata.key.blob.is_some())
353 || key_metadata.key.blob.is_none()
354 );
355
356 Ok(key_metadata)
357}
Rajesh Nyamagoud47409932022-01-08 00:37:13 +0000358
Rajesh Nyamagoudc3523ba2022-08-05 17:38:25 +0000359/// Generate AES/3DES key.
360pub fn generate_sym_key(
Rajesh Nyamagoud47409932022-01-08 00:37:13 +0000361 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
Rajesh Nyamagoudc3523ba2022-08-05 17:38:25 +0000362 algorithm: Algorithm,
Rajesh Nyamagoud47409932022-01-08 00:37:13 +0000363 size: i32,
364 alias: &str,
365 padding_mode: &PaddingMode,
366 block_mode: &BlockMode,
367 min_mac_len: Option<i32>,
368) -> binder::Result<KeyMetadata> {
369 let mut gen_params = AuthSetBuilder::new()
370 .no_auth_required()
Rajesh Nyamagoudc3523ba2022-08-05 17:38:25 +0000371 .algorithm(algorithm)
Rajesh Nyamagoud47409932022-01-08 00:37:13 +0000372 .purpose(KeyPurpose::ENCRYPT)
373 .purpose(KeyPurpose::DECRYPT)
374 .key_size(size)
375 .padding_mode(*padding_mode)
376 .block_mode(*block_mode);
377
378 if let Some(val) = min_mac_len {
379 gen_params = gen_params.min_mac_length(val);
380 }
381
382 let key_metadata = sec_level.generateKey(
383 &KeyDescriptor {
384 domain: Domain::APP,
385 nspace: -1,
386 alias: Some(alias.to_string()),
387 blob: None,
388 },
389 None,
390 &gen_params,
391 0,
392 b"entropy",
393 )?;
394
395 // Should not have public certificate.
396 assert!(key_metadata.certificate.is_none());
397
398 // Should not have an attestation record.
399 assert!(key_metadata.certificateChain.is_none());
400 Ok(key_metadata)
401}
Rajesh Nyamagoud4c6193c2022-02-03 01:15:34 +0000402
403/// Generate HMAC key.
404pub fn generate_hmac_key(
405 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
406 alias: &str,
407 key_size: i32,
408 min_mac_len: i32,
409 digest: Digest,
410) -> binder::Result<KeyMetadata> {
411 let gen_params = AuthSetBuilder::new()
412 .no_auth_required()
413 .algorithm(Algorithm::HMAC)
414 .purpose(KeyPurpose::SIGN)
415 .purpose(KeyPurpose::VERIFY)
416 .key_size(key_size)
417 .min_mac_length(min_mac_len)
418 .digest(digest);
419
420 let key_metadata = sec_level.generateKey(
421 &KeyDescriptor {
422 domain: Domain::APP,
423 nspace: -1,
424 alias: Some(alias.to_string()),
425 blob: None,
426 },
427 None,
428 &gen_params,
429 0,
430 b"entropy",
431 )?;
432
433 // Should not have public certificate.
434 assert!(key_metadata.certificate.is_none());
435
436 // Should not have an attestation record.
437 assert!(key_metadata.certificateChain.is_none());
438
439 Ok(key_metadata)
440}
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +0000441
442/// Generate RSA or EC attestation keys using below parameters -
443/// Purpose: ATTEST_KEY
444/// Digest: Digest::SHA_2_256
445/// Padding: PaddingMode::RSA_PKCS1_1_5_SIGN
446/// RSA-Key-Size: 2048
447/// EC-Curve: EcCurve::P_256
448pub fn generate_attestation_key(
449 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
450 algorithm: Algorithm,
451 att_challenge: &[u8],
452 att_app_id: &[u8],
453) -> binder::Result<KeyMetadata> {
454 assert!(algorithm == Algorithm::RSA || algorithm == Algorithm::EC);
455
456 if algorithm == Algorithm::RSA {
457 let alias = "ks_rsa_attest_test_key";
458 let metadata = generate_rsa_key(
459 sec_level,
460 Domain::APP,
461 -1,
462 Some(alias.to_string()),
463 &KeyParams {
464 key_size: 2048,
465 purpose: vec![KeyPurpose::ATTEST_KEY],
466 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
467 digest: Some(Digest::SHA_2_256),
468 mgf_digest: None,
469 block_mode: None,
470 att_challenge: Some(att_challenge.to_vec()),
471 att_app_id: Some(att_app_id.to_vec()),
472 },
473 None,
474 )
475 .unwrap();
476 Ok(metadata)
477 } else {
478 let metadata = generate_ec_attestation_key(
479 sec_level,
480 att_challenge,
481 att_app_id,
482 Digest::SHA_2_256,
483 EcCurve::P_256,
484 )
485 .unwrap();
486
487 Ok(metadata)
488 }
489}
490
491/// Generate EC attestation key with the given
492/// curve, attestation-challenge and attestation-app-id.
493pub fn generate_ec_attestation_key(
494 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
495 att_challenge: &[u8],
496 att_app_id: &[u8],
497 digest: Digest,
498 ec_curve: EcCurve,
499) -> binder::Result<KeyMetadata> {
500 let alias = "ks_attest_ec_test_key";
501 let gen_params = AuthSetBuilder::new()
502 .no_auth_required()
503 .algorithm(Algorithm::EC)
504 .purpose(KeyPurpose::ATTEST_KEY)
505 .ec_curve(ec_curve)
506 .digest(digest)
507 .attestation_challenge(att_challenge.to_vec())
508 .attestation_app_id(att_app_id.to_vec());
509
510 let attestation_key_metadata = sec_level.generateKey(
511 &KeyDescriptor {
512 domain: Domain::APP,
513 nspace: -1,
514 alias: Some(alias.to_string()),
515 blob: None,
516 },
517 None,
518 &gen_params,
519 0,
520 b"entropy",
521 )?;
522
523 // Should have public certificate.
524 assert!(attestation_key_metadata.certificate.is_some());
525 // Should have an attestation record.
526 assert!(attestation_key_metadata.certificateChain.is_some());
527
528 Ok(attestation_key_metadata)
529}
530
531/// Generate EC-P-256 key and attest it with given attestation key.
532pub fn generate_ec_256_attested_key(
533 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
534 alias: Option<String>,
535 att_challenge: &[u8],
536 att_app_id: &[u8],
537 attest_key: &KeyDescriptor,
538) -> binder::Result<KeyMetadata> {
539 let ec_gen_params = AuthSetBuilder::new()
540 .no_auth_required()
541 .algorithm(Algorithm::EC)
542 .purpose(KeyPurpose::SIGN)
543 .purpose(KeyPurpose::VERIFY)
544 .digest(Digest::SHA_2_256)
545 .ec_curve(EcCurve::P_256)
546 .attestation_challenge(att_challenge.to_vec())
547 .attestation_app_id(att_app_id.to_vec());
548
549 let ec_key_metadata = sec_level
550 .generateKey(
551 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: None },
552 Some(attest_key),
553 &ec_gen_params,
554 0,
555 b"entropy",
556 )
557 .unwrap();
558
559 // Should have public certificate.
560 assert!(ec_key_metadata.certificate.is_some());
561 // Shouldn't have an attestation record.
562 assert!(ec_key_metadata.certificateChain.is_none());
563
564 Ok(ec_key_metadata)
565}
Rajesh Nyamagoudb8402b62022-04-08 01:05:47 +0000566
567fn check_key_param(authorizations: &[Authorization], key_param: KeyParameter) -> bool {
568 for authrization in authorizations {
569 if authrization.keyParameter == key_param {
570 return true;
571 }
572 }
573
574 false
575}
576
577/// Imports above defined RSA key - `RSA_2048_KEY` and validates imported key parameters.
578pub fn import_rsa_2048_key(
579 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
580 domain: Domain,
581 nspace: i64,
582 alias: Option<String>,
583 import_params: AuthSetBuilder,
584) -> binder::Result<KeyMetadata> {
585 let key_metadata = sec_level
586 .importKey(
587 &KeyDescriptor { domain, nspace, alias, blob: None },
588 None,
589 &import_params,
590 0,
591 RSA_2048_KEY,
592 )
593 .unwrap();
594
595 assert!(key_metadata.certificate.is_some());
596 assert!(key_metadata.certificateChain.is_none());
597
598 assert!(check_key_param(
599 &key_metadata.authorizations,
600 KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::RSA) }
601 ));
602
603 assert!(check_key_param(
604 &key_metadata.authorizations,
605 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
606 ));
607
608 assert!(check_key_param(
609 &key_metadata.authorizations,
610 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
611 ));
612
613 assert!(check_key_param(
614 &key_metadata.authorizations,
615 KeyParameter {
616 tag: Tag::RSA_PUBLIC_EXPONENT,
617 value: KeyParameterValue::LongInteger(65537)
618 }
619 ));
620
621 assert!(check_key_param(
622 &key_metadata.authorizations,
623 KeyParameter {
624 tag: Tag::PADDING,
625 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
626 }
627 ));
628
629 assert!(check_key_param(
630 &key_metadata.authorizations,
631 KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
632 ));
633
634 Ok(key_metadata)
635}
636
637/// Imports above defined EC key - `EC_P_256_KEY` and validates imported key parameters.
638pub fn import_ec_p_256_key(
639 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
640 domain: Domain,
641 nspace: i64,
642 alias: Option<String>,
643 import_params: AuthSetBuilder,
644) -> binder::Result<KeyMetadata> {
645 let key_metadata = sec_level
646 .importKey(
647 &KeyDescriptor { domain, nspace, alias, blob: None },
648 None,
649 &import_params,
650 0,
651 EC_P_256_KEY,
652 )
653 .unwrap();
654
655 assert!(key_metadata.certificate.is_some());
656 assert!(key_metadata.certificateChain.is_none());
657
658 assert!(check_key_param(
659 &key_metadata.authorizations,
660 KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::EC) }
661 ));
662
663 assert!(check_key_param(
664 &key_metadata.authorizations,
665 KeyParameter { tag: Tag::EC_CURVE, value: KeyParameterValue::EcCurve(EcCurve::P_256) }
666 ));
667
668 assert!(check_key_param(
669 &key_metadata.authorizations,
670 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
671 ));
672 assert!(check_key_param(
673 &key_metadata.authorizations,
674 KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
675 ));
676
677 Ok(key_metadata)
678}
679
680/// Import sample AES key and validate its key parameters.
681pub fn import_aes_key(
682 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
683 domain: Domain,
684 nspace: i64,
685 alias: Option<String>,
686) -> binder::Result<KeyMetadata> {
687 static AES_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
688 let key_size = AES_KEY.len() * 8;
689
690 let import_params = AuthSetBuilder::new()
691 .no_auth_required()
692 .algorithm(Algorithm::AES)
693 .block_mode(BlockMode::ECB)
694 .key_size(key_size.try_into().unwrap())
695 .purpose(KeyPurpose::ENCRYPT)
696 .purpose(KeyPurpose::DECRYPT)
697 .padding_mode(PaddingMode::PKCS7);
698
699 let key_metadata = sec_level.importKey(
700 &KeyDescriptor { domain, nspace, alias, blob: None },
701 None,
702 &import_params,
703 0,
704 AES_KEY,
705 )?;
706
707 assert!(check_key_param(
708 &key_metadata.authorizations,
709 KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::AES) }
710 ));
711 assert!(check_key_param(
712 &key_metadata.authorizations,
713 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
714 ));
715 assert!(check_key_param(
716 &key_metadata.authorizations,
717 KeyParameter {
718 tag: Tag::PADDING,
719 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
720 }
721 ));
722 assert!(check_key_param(
723 &key_metadata.authorizations,
724 KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
725 ));
726 assert!(check_key_param(
727 &key_metadata.authorizations,
728 KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
729 ));
730
731 Ok(key_metadata)
732}
733
734/// Import sample 3DES key and validate its key parameters.
735pub fn import_3des_key(
736 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
737 domain: Domain,
738 nspace: i64,
739 alias: Option<String>,
740) -> binder::Result<KeyMetadata> {
741 static TRIPLE_DES_KEY: &[u8] = &[
742 0xa4, 0x9d, 0x75, 0x64, 0x19, 0x9e, 0x97, 0xcb, 0x52, 0x9d, 0x2c, 0x9d, 0x97, 0xbf, 0x2f,
743 0x98, 0xd3, 0x5e, 0xdf, 0x57, 0xba, 0x1f, 0x73, 0x58,
744 ];
745
746 let import_params = AuthSetBuilder::new()
747 .no_auth_required()
748 .algorithm(Algorithm::TRIPLE_DES)
749 .block_mode(BlockMode::ECB)
750 .key_size(168)
751 .purpose(KeyPurpose::ENCRYPT)
752 .purpose(KeyPurpose::DECRYPT)
753 .padding_mode(PaddingMode::PKCS7);
754
755 let key_metadata = sec_level.importKey(
756 &KeyDescriptor { domain, nspace, alias, blob: None },
757 None,
758 &import_params,
759 0,
760 TRIPLE_DES_KEY,
761 )?;
762
763 assert!(check_key_param(
764 &key_metadata.authorizations,
765 KeyParameter {
766 tag: Tag::ALGORITHM,
767 value: KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES)
768 }
769 ));
770 assert!(check_key_param(
771 &key_metadata.authorizations,
772 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(168) }
773 ));
774 assert!(check_key_param(
775 &key_metadata.authorizations,
776 KeyParameter {
777 tag: Tag::PADDING,
778 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
779 }
780 ));
781 assert!(check_key_param(
782 &key_metadata.authorizations,
783 KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
784 ));
785 assert!(check_key_param(
786 &key_metadata.authorizations,
787 KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
788 ));
789
790 Ok(key_metadata)
791}
792
793/// Import sample HMAC key and validate its key parameters.
794pub fn import_hmac_key(
795 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
796 domain: Domain,
797 nspace: i64,
798 alias: Option<String>,
799) -> binder::Result<KeyMetadata> {
800 static HMAC_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
801 let key_size = HMAC_KEY.len() * 8;
802
803 let import_params = AuthSetBuilder::new()
804 .no_auth_required()
805 .algorithm(Algorithm::HMAC)
806 .key_size(key_size.try_into().unwrap())
807 .purpose(KeyPurpose::SIGN)
808 .purpose(KeyPurpose::VERIFY)
809 .digest(Digest::SHA_2_256)
810 .min_mac_length(256);
811
812 let key_metadata = sec_level.importKey(
813 &KeyDescriptor { domain, nspace, alias, blob: None },
814 None,
815 &import_params,
816 0,
817 HMAC_KEY,
818 )?;
819
820 assert!(check_key_param(
821 &key_metadata.authorizations,
822 KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::HMAC) }
823 ));
824 assert!(check_key_param(
825 &key_metadata.authorizations,
826 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
827 ));
828 assert!(check_key_param(
829 &key_metadata.authorizations,
830 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
831 ));
832 assert!(check_key_param(
833 &key_metadata.authorizations,
834 KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
835 ));
836
837 Ok(key_metadata)
838}