Skip to content

Commit 5cbdd59

Browse files
committed
trusted: add the trusted keytype
1 parent b4a4bf3 commit 5cbdd59

File tree

4 files changed

+231
-3
lines changed

4 files changed

+231
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ members = ["libkeyutils-sys"]
1717
[dependencies]
1818
bitflags = "^1.0"
1919
errno = "~0.2"
20+
itertools = "~0.8"
2021
libkeyutils-sys = { path = "libkeyutils-sys", version = "~0.3.1" }
2122
log = "~0.4"
2223

2324
libc = "~0.2"
24-
25-
[features]
26-
nightly = ["itertools"]

src/keytypes/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub use self::keyring::Keyring;
5252
pub mod logon;
5353
pub use self::logon::Logon;
5454

55+
pub mod trusted;
56+
pub use self::trusted::Trusted;
57+
5558
pub mod user;
5659
pub use self::user::User;
5760

src/keytypes/trusted.rs

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
// Copyright (c) 2015, Ben Boeckel
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// * Neither the name of this project nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23+
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
//! Trusted keys
28+
29+
use crates::itertools::Itertools;
30+
31+
use keytype::*;
32+
use keytypes::AsciiHex;
33+
34+
use std::borrow::Cow;
35+
36+
/// Trusted keys are rooted in the TPM.
37+
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
38+
pub struct Trusted;
39+
40+
impl KeyType for Trusted {
41+
/// Trusted key descriptions are free-form.
42+
type Description = str;
43+
type Payload = Payload;
44+
45+
fn name() -> &'static str {
46+
"trusted"
47+
}
48+
}
49+
50+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51+
pub enum TpmHash {
52+
/// SHA-1
53+
Sha1,
54+
/// SHA-256
55+
///
56+
/// Requires TPM2.
57+
Sha256,
58+
/// SHA-384
59+
///
60+
/// Requires TPM2.
61+
Sha384,
62+
/// SHA-512
63+
///
64+
/// Requires TPM2.
65+
Sha512,
66+
/// sm3-256
67+
///
68+
/// Requires TPM2.
69+
Sm3_256,
70+
}
71+
72+
impl TpmHash {
73+
fn name(self) -> &'static str {
74+
match self {
75+
TpmHash::Sha1 => "sha1",
76+
TpmHash::Sha256 => "sha256",
77+
TpmHash::Sha384 => "sha384",
78+
TpmHash::Sha512 => "sha512",
79+
TpmHash::Sm3_256 => "sm3-256",
80+
}
81+
}
82+
}
83+
84+
#[derive(Debug, Default, Clone, PartialEq, Eq)]
85+
pub struct TrustedOptions {
86+
/// The ID of the sealing key to use.
87+
pub keyhandle: Option<u32>,
88+
/// The authorization for sealing keys.
89+
pub keyauth: Option<[u8; 20]>,
90+
/// The authorization for sealing data.
91+
pub blobauth: Option<[u8; 20]>,
92+
// TODO: What is this?
93+
pub pcrinfo: Option<Vec<u8>>,
94+
/// The PCR in the TPM to extend and lock the key.
95+
///
96+
/// Only makes sense during a `Load` operation.
97+
pub pcrlock: Option<u32>,
98+
/// Whether the key may be resealed using new PCR value.
99+
///
100+
/// Defaults to `true` if unspecified.
101+
pub migratable: Option<bool>,
102+
/// The hash algorithm to use.
103+
pub hash: Option<TpmHash>,
104+
/// The hash digest for the authorization policy.
105+
///
106+
/// The digest must have been generated using the specified `TpmHash`.
107+
pub policydigest: Option<Vec<u8>>,
108+
/// The session handle for the policy.
109+
pub policyhandle: Option<u32>,
110+
}
111+
112+
impl TrustedOptions {
113+
fn payload_string(&self) -> String {
114+
let parts = [
115+
// keyhandle= ascii hex value of sealing key; default 40000000 (SRK)
116+
(
117+
"keyhandle",
118+
self.keyhandle
119+
.as_ref()
120+
.map(|v| AsciiHex::convert(&v.to_be().to_be_bytes())),
121+
),
122+
// keyauth= ascii hex auth for sealing key; default 00...
123+
// (40 ascii zeros)
124+
(
125+
"keyauth",
126+
self.keyauth.as_ref().map(|v| AsciiHex::convert(v)),
127+
),
128+
// blobauth= ascii hex auth for sealed data; default 00...
129+
// (40 ascii zeros)
130+
(
131+
"blobauth",
132+
self.blobauth.as_ref().map(|v| AsciiHex::convert(v)),
133+
),
134+
// pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
135+
(
136+
"pcrinfo",
137+
self.pcrinfo.as_ref().map(|v| AsciiHex::convert(&v)),
138+
),
139+
// pcrlock= pcr number to be extended to "lock" blob
140+
("pcrlock", self.pcrlock.as_ref().map(|v| format!("{}", v))),
141+
// migratable= 0|1 indicating permission to reseal to new PCR values,
142+
// default 1 (resealing allowed)
143+
(
144+
"migratable",
145+
self.migratable
146+
.as_ref()
147+
.map(|&v| if v { "1" } else { "0" }.to_string()),
148+
),
149+
// hash= hash algorithm name as a string. For TPM 1.x the only
150+
// allowed value is sha1. For TPM 2.x the allowed values
151+
// are sha1, sha256, sha384, sha512 and sm3-256.
152+
("hash", self.hash.as_ref().map(|v| v.name().to_string())),
153+
// policydigest= digest for the authorization policy. must be calculated
154+
// with the same hash algorithm as specified by the 'hash='
155+
// option.
156+
(
157+
"policydigest",
158+
self.policydigest.as_ref().map(|v| AsciiHex::convert(&v)),
159+
),
160+
// policyhandle= handle to an authorization policy session that defines the
161+
// same policy and with the same hash algorithm as was used to
162+
// seal the key.
163+
(
164+
"policyhandle",
165+
self.policyhandle
166+
.as_ref()
167+
.map(|v| AsciiHex::convert(&v.to_be().to_be_bytes())),
168+
),
169+
];
170+
171+
let options = parts
172+
.into_iter()
173+
.filter_map(|(key, value)| value.as_ref().map(|value| format!("{}={}", key, value)))
174+
.format(" ");
175+
176+
format!("{}", options)
177+
}
178+
}
179+
180+
#[derive(Debug, Clone, PartialEq, Eq)]
181+
pub enum Payload {
182+
/// Create a new key.
183+
///
184+
/// Use this with `add_key`.
185+
New {
186+
/// The size of the key to generate.
187+
keylen: usize,
188+
/// Options for the new key.
189+
options: TrustedOptions,
190+
},
191+
/// Load a blob into the TPM.
192+
///
193+
/// Use this with `add_key`.
194+
Load {
195+
/// The blob to load into the TPM.
196+
blob: Vec<u8>,
197+
/// Options for loading.
198+
options: TrustedOptions,
199+
},
200+
/// Update a key.
201+
///
202+
/// Use this with `update`.
203+
Update { options: TrustedOptions },
204+
}
205+
206+
impl KeyPayload for Payload {
207+
fn payload(&self) -> Cow<[u8]> {
208+
let (command, blob, options) = match *self {
209+
Payload::New {
210+
ref keylen,
211+
ref options,
212+
} => ("new", format!("{}", keylen), options),
213+
Payload::Load {
214+
ref blob,
215+
ref options,
216+
} => ("load", AsciiHex::convert(&blob), options),
217+
Payload::Update {
218+
ref options,
219+
} => ("update", String::new(), options),
220+
};
221+
222+
format!("{} {} {}", command, blob, options.payload_string())
223+
.bytes()
224+
.collect()
225+
}
226+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ mod crates {
4242

4343
// private
4444
pub extern crate errno;
45+
pub extern crate itertools;
4546
pub extern crate libkeyutils_sys;
4647
}
4748

0 commit comments

Comments
 (0)