tink_core/cryptofmt/mod.rs
1// Copyright 2020 The Tink-Rust Authors
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////////////////////////////////////////////////////////////////////////////////
16
17//! Provides constants and convenience methods that define the format of ciphertexts and signatures.
18
19use crate::TinkError;
20use std::convert::TryFrom;
21use tink_proto::OutputPrefixType;
22
23/// Prefix size of Tink and Legacy key types.
24pub const NON_RAW_PREFIX_SIZE: usize = 5;
25
26/// Prefix size of legacy key types.
27/// The prefix starts with \x00 and followed by a 4-byte key id.
28pub const LEGACY_PREFIX_SIZE: usize = NON_RAW_PREFIX_SIZE;
29/// First byte of the prefix of legacy key types.
30pub const LEGACY_START_BYTE: u8 = 0;
31
32/// Prefix size of Tink key types.
33/// The prefix starts with \x01 and followed by a 4-byte key id.
34pub const TINK_PREFIX_SIZE: usize = NON_RAW_PREFIX_SIZE;
35/// First byte of the prefix of Tink key types.
36pub const TINK_START_BYTE: u8 = 1;
37
38/// Prefix size of Raw key types.
39/// Raw prefix is empty.
40pub const RAW_PREFIX_SIZE: usize = 0;
41/// Empty prefix for Raw key types.
42pub const RAW_PREFIX: Vec<u8> = Vec::new();
43
44/// Generate the prefix of ciphertexts produced by the crypto primitive obtained from key.
45///
46/// The prefix can be either empty (for RAW-type prefix), or consists of a 1-byte indicator of the
47/// type of the prefix, followed by 4 bytes of the key ID in big endian encoding.
48pub fn output_prefix(key: &tink_proto::keyset::Key) -> Result<Vec<u8>, TinkError> {
49 match OutputPrefixType::try_from(key.output_prefix_type) {
50 Ok(OutputPrefixType::Legacy) | Ok(OutputPrefixType::Crunchy) => Ok(create_output_prefix(
51 LEGACY_PREFIX_SIZE,
52 LEGACY_START_BYTE,
53 key.key_id,
54 )),
55 Ok(OutputPrefixType::Tink) => Ok(create_output_prefix(
56 TINK_PREFIX_SIZE,
57 TINK_START_BYTE,
58 key.key_id,
59 )),
60 Ok(OutputPrefixType::Raw) => Ok(RAW_PREFIX),
61 Ok(OutputPrefixType::UnknownPrefix) | Err(_) => {
62 Err("cryptofmt: unknown output prefix type".into())
63 }
64 }
65}
66
67/// Build a vector of requested size with key ID prefix pre-filled.
68fn create_output_prefix(size: usize, start_byte: u8, key_id: crate::KeyId) -> Vec<u8> {
69 let mut prefix = Vec::with_capacity(size);
70 prefix.push(start_byte);
71 prefix.extend_from_slice(&key_id.to_be_bytes());
72 prefix
73}