1// Copyright 2019 Google LLC 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// Package cryptofmt provides constants and convenience methods that define the 18// format of ciphertexts and signatures. 19package cryptofmt 20 21import ( 22 "encoding/binary" 23 "fmt" 24 25 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 26) 27 28const ( 29 // NonRawPrefixSize is the prefix size of Tink and Legacy key types. 30 NonRawPrefixSize = 5 31 32 // LegacyPrefixSize is the prefix size of legacy key types. 33 // The prefix starts with \x00 and followed by a 4-byte key id. 34 LegacyPrefixSize = NonRawPrefixSize 35 // LegacyStartByte is the first byte of the prefix of legacy key types. 36 LegacyStartByte = byte(0) 37 38 // TinkPrefixSize is the prefix size of Tink key types. 39 // The prefix starts with \x01 and followed by a 4-byte key id. 40 TinkPrefixSize = NonRawPrefixSize 41 // TinkStartByte is the first byte of the prefix of Tink key types. 42 TinkStartByte = byte(1) 43 44 // RawPrefixSize is the prefix size of Raw key types. 45 // Raw prefix is empty. 46 RawPrefixSize = 0 47 // RawPrefix is the empty prefix of Raw key types. 48 RawPrefix = "" 49) 50 51// OutputPrefix generates the prefix of ciphertexts produced by the crypto 52// primitive obtained from key. The prefix can be either empty (for RAW-type 53// prefix), or consists of a 1-byte indicator of the type of the prefix, 54// followed by 4 bytes of the key ID in big endian encoding. 55func OutputPrefix(key *tinkpb.Keyset_Key) (string, error) { 56 switch key.OutputPrefixType { 57 case tinkpb.OutputPrefixType_LEGACY, tinkpb.OutputPrefixType_CRUNCHY: 58 return createOutputPrefix(LegacyPrefixSize, LegacyStartByte, key.KeyId), nil 59 case tinkpb.OutputPrefixType_TINK: 60 return createOutputPrefix(TinkPrefixSize, TinkStartByte, key.KeyId), nil 61 case tinkpb.OutputPrefixType_RAW: 62 return RawPrefix, nil 63 default: 64 return "", fmt.Errorf("crypto_format: unknown output prefix type") 65 } 66} 67 68func createOutputPrefix(size int, startByte byte, keyID uint32) string { 69 prefix := make([]byte, size) 70 prefix[0] = startByte 71 binary.BigEndian.PutUint32(prefix[1:], keyID) 72 return string(prefix) 73} 74