github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/kbfscrypto/encrypted_data.go (about) 1 // Copyright 2017 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package kbfscrypto 6 7 import ( 8 "bytes" 9 "encoding/hex" 10 "fmt" 11 "reflect" 12 13 "github.com/keybase/client/go/kbfs/cache" 14 "github.com/keybase/client/go/kbfs/kbfscodec" 15 "github.com/keybase/client/go/kbfs/kbfshash" 16 "github.com/keybase/client/go/libkb" 17 "github.com/pkg/errors" 18 "golang.org/x/crypto/nacl/box" 19 "golang.org/x/crypto/nacl/secretbox" 20 ) 21 22 // EncryptionVer denotes a version for the encryption method. 23 type EncryptionVer int 24 25 const ( 26 // EncryptionSecretbox is the encryption version that uses 27 // nacl/secretbox or nacl/box. 28 EncryptionSecretbox EncryptionVer = 1 29 // EncryptionSecretboxWithKeyNonce is the encryption version that 30 // uses nacl/secretbox or nacl/box, with a nonce derived from a 31 // secret key. 32 EncryptionSecretboxWithKeyNonce EncryptionVer = 2 33 ) 34 35 func (v EncryptionVer) String() string { 36 switch v { 37 case EncryptionSecretbox: 38 return "EncryptionSecretbox" 39 case EncryptionSecretboxWithKeyNonce: 40 return "EncryptionSecretboxWithKeyNonce" 41 default: 42 return fmt.Sprintf("EncryptionVer(%d)", v) 43 } 44 } 45 46 // ToHashType returns the type of the hash that should be used for the 47 // given encryption version. 48 func (v EncryptionVer) ToHashType() kbfshash.HashType { 49 switch v { 50 case EncryptionSecretbox: 51 return kbfshash.SHA256Hash 52 case EncryptionSecretboxWithKeyNonce: 53 return kbfshash.SHA256HashV2 54 default: 55 return kbfshash.InvalidHash 56 } 57 } 58 59 // encryptedData is encrypted data with a nonce and a version. 60 type encryptedData struct { 61 // Exported only for serialization purposes. Should only be 62 // used by implementations of Crypto. 63 Version EncryptionVer `codec:"v"` 64 EncryptedData []byte `codec:"e"` 65 Nonce []byte `codec:"n"` 66 } 67 68 // Size implements the cache.Measurable interface. 69 func (ed encryptedData) Size() int { 70 return cache.IntSize /* ed.Version */ + 71 cache.PtrSize + len(ed.EncryptedData) + cache.PtrSize + len(ed.Nonce) 72 } 73 74 func (ed encryptedData) String() string { 75 if reflect.DeepEqual(ed, encryptedData{}) { 76 return "EncryptedData{}" 77 } 78 return fmt.Sprintf("%s{data=%s, nonce=%s}", 79 ed.Version, hex.EncodeToString(ed.EncryptedData), 80 hex.EncodeToString(ed.Nonce)) 81 } 82 83 func (ed encryptedData) Nonce24() (nonce [24]byte, err error) { 84 if len(ed.Nonce) != len(nonce) { 85 return nonce, errors.WithStack(InvalidNonceError{ed.Nonce}) 86 } 87 copy(nonce[:], ed.Nonce) 88 return nonce, nil 89 } 90 91 // encryptDataWithNonce encrypts the given data with the given 92 // symmetric key and nonce. 93 func encryptDataWithNonce( 94 data []byte, key [32]byte, nonce [24]byte, ver EncryptionVer) ( 95 encryptedData, error) { 96 sealedData := secretbox.Seal(nil, data, &nonce, &key) 97 98 return encryptedData{ 99 Version: ver, 100 Nonce: nonce[:], 101 EncryptedData: sealedData, 102 }, nil 103 } 104 105 // encryptData encrypts the given data with the given symmetric key. 106 func encryptData(data []byte, key [32]byte) (encryptedData, error) { 107 var nonce [24]byte 108 err := RandRead(nonce[:]) 109 if err != nil { 110 return encryptedData{}, err 111 } 112 113 return encryptDataWithNonce(data, key, nonce, EncryptionSecretbox) 114 } 115 116 // decryptData decrypts the given encrypted data with the given 117 // symmetric key and nonce. 118 func decryptData( 119 encryptedData encryptedData, key [32]byte, nonce [24]byte) ([]byte, error) { 120 switch encryptedData.Version { 121 case EncryptionSecretbox: 122 // We're good, no nonce check needed. 123 case EncryptionSecretboxWithKeyNonce: 124 if !bytes.Equal(nonce[:], encryptedData.Nonce) { 125 return nil, errors.WithStack(InvalidNonceError{encryptedData.Nonce}) 126 } 127 default: 128 return nil, errors.WithStack( 129 UnknownEncryptionVer{encryptedData.Version}) 130 } 131 132 decryptedData, ok := secretbox.Open( 133 nil, encryptedData.EncryptedData, &nonce, &key) 134 if !ok { 135 return nil, errors.WithStack( 136 libkb.DecryptionError{Cause: libkb.ErrorCause{Err: errors.New("Cannot open secret box")}}) 137 } 138 139 return decryptedData, nil 140 } 141 142 // EncryptedTLFCryptKeyClientHalf is an encrypted 143 // TLFCryptKeyClientHalf object. 144 type EncryptedTLFCryptKeyClientHalf struct { 145 encryptedData 146 } 147 148 // EncryptTLFCryptKeyClientHalf encrypts a TLFCryptKeyClientHalf 149 // using both a TLF's ephemeral private key and a device pubkey. 150 func EncryptTLFCryptKeyClientHalf( 151 privateKey TLFEphemeralPrivateKey, publicKey CryptPublicKey, 152 clientHalf TLFCryptKeyClientHalf) ( 153 encryptedClientHalf EncryptedTLFCryptKeyClientHalf, err error) { 154 var nonce [24]byte 155 err = RandRead(nonce[:]) 156 if err != nil { 157 return EncryptedTLFCryptKeyClientHalf{}, err 158 } 159 160 keypair, err := libkb.ImportKeypairFromKID(publicKey.KID()) 161 if err != nil { 162 return EncryptedTLFCryptKeyClientHalf{}, errors.WithStack(err) 163 } 164 165 dhKeyPair, ok := keypair.(libkb.NaclDHKeyPair) 166 if !ok { 167 return EncryptedTLFCryptKeyClientHalf{}, errors.WithStack( 168 libkb.KeyCannotEncryptError{}) 169 } 170 171 clientHalfData := clientHalf.Data() 172 privateKeyData := privateKey.Data() 173 encryptedBytes := box.Seal(nil, clientHalfData[:], &nonce, (*[32]byte)(&dhKeyPair.Public), &privateKeyData) 174 175 return EncryptedTLFCryptKeyClientHalf{ 176 encryptedData{ 177 Version: EncryptionSecretbox, 178 EncryptedData: encryptedBytes, 179 Nonce: nonce[:], 180 }, 181 }, nil 182 } 183 184 // EncryptedPrivateMetadata is an encrypted PrivateMetadata object. 185 type EncryptedPrivateMetadata struct { 186 encryptedData 187 } 188 189 // EncryptEncodedPrivateMetadata encrypts an encoded PrivateMetadata 190 // object. 191 func EncryptEncodedPrivateMetadata(encodedPrivateMetadata []byte, key TLFCryptKey) ( 192 encryptedPrivateMetadata EncryptedPrivateMetadata, err error) { 193 encryptedData, err := encryptData(encodedPrivateMetadata, key.Data()) 194 if err != nil { 195 return EncryptedPrivateMetadata{}, err 196 } 197 198 return EncryptedPrivateMetadata{encryptedData}, nil 199 } 200 201 // DecryptPrivateMetadata decrypts a PrivateMetadata object, but does 202 // not decode it. 203 func DecryptPrivateMetadata( 204 encryptedPrivateMetadata EncryptedPrivateMetadata, key TLFCryptKey) ( 205 []byte, error) { 206 if encryptedPrivateMetadata.encryptedData.Version == 207 EncryptionSecretboxWithKeyNonce { 208 // Only blocks should have v2 encryption. 209 return nil, errors.WithStack(InvalidEncryptionVer{ 210 encryptedPrivateMetadata.encryptedData.Version}) 211 } 212 213 nonce, err := encryptedPrivateMetadata.encryptedData.Nonce24() 214 if err != nil { 215 return nil, err 216 } 217 218 return decryptData( 219 encryptedPrivateMetadata.encryptedData, key.Data(), nonce) 220 } 221 222 // EncryptedBlock is an encrypted Block object. 223 type EncryptedBlock struct { 224 encryptedData 225 } 226 227 // EncryptPaddedEncodedBlock encrypts a padded, encoded block. 228 func EncryptPaddedEncodedBlock( 229 paddedEncodedBlock []byte, tlfCryptKey TLFCryptKey, 230 blockServerHalf BlockCryptKeyServerHalf, ver EncryptionVer) ( 231 encryptedBlock EncryptedBlock, err error) { 232 var ed encryptedData 233 switch ver { 234 case EncryptionSecretbox: 235 key := UnmaskBlockCryptKey(blockServerHalf, tlfCryptKey) 236 ed, err = encryptData(paddedEncodedBlock, key.Data()) 237 if err != nil { 238 return EncryptedBlock{}, err 239 } 240 case EncryptionSecretboxWithKeyNonce: 241 key := MakeBlockHashKey(blockServerHalf, tlfCryptKey) 242 ed, err = encryptDataWithNonce( 243 paddedEncodedBlock, key.cryptKey(), key.nonce(), 244 EncryptionSecretboxWithKeyNonce) 245 if err != nil { 246 return EncryptedBlock{}, err 247 } 248 default: 249 return EncryptedBlock{}, errors.WithStack(UnknownEncryptionVer{ver}) 250 } 251 252 return EncryptedBlock{ed}, nil 253 } 254 255 // DecryptBlock decrypts a block, but does not unpad or decode it. 256 func DecryptBlock( 257 encryptedBlock EncryptedBlock, tlfCryptKey TLFCryptKey, 258 blockServerHalf BlockCryptKeyServerHalf) ([]byte, error) { 259 switch encryptedBlock.encryptedData.Version { 260 case EncryptionSecretbox: 261 nonce, err := encryptedBlock.encryptedData.Nonce24() 262 if err != nil { 263 return nil, err 264 } 265 266 key := UnmaskBlockCryptKey(blockServerHalf, tlfCryptKey) 267 return decryptData(encryptedBlock.encryptedData, key.Data(), nonce) 268 case EncryptionSecretboxWithKeyNonce: 269 key := MakeBlockHashKey(blockServerHalf, tlfCryptKey) 270 return decryptData( 271 encryptedBlock.encryptedData, key.cryptKey(), key.nonce()) 272 default: 273 return nil, errors.WithStack( 274 InvalidEncryptionVer{encryptedBlock.encryptedData.Version}) 275 } 276 } 277 278 // EncryptedTLFCryptKeys is an encrypted TLFCryptKey array. 279 type EncryptedTLFCryptKeys struct { 280 encryptedData 281 } 282 283 // EncryptTLFCryptKeys encrypts a TLFCryptKey array. 284 func EncryptTLFCryptKeys(codec kbfscodec.Codec, oldKeys []TLFCryptKey, key TLFCryptKey) ( 285 encryptedTLFCryptKeys EncryptedTLFCryptKeys, err error) { 286 encodedKeys, err := codec.Encode(oldKeys) 287 if err != nil { 288 return EncryptedTLFCryptKeys{}, err 289 } 290 291 encryptedData, err := encryptData(encodedKeys, key.Data()) 292 if err != nil { 293 return EncryptedTLFCryptKeys{}, err 294 } 295 296 return EncryptedTLFCryptKeys{encryptedData}, nil 297 } 298 299 // DecryptTLFCryptKeys decrypts a TLFCryptKey array, but does not 300 // decode it. 301 func DecryptTLFCryptKeys( 302 codec kbfscodec.Codec, encryptedTLFCryptKeys EncryptedTLFCryptKeys, key TLFCryptKey) ( 303 []TLFCryptKey, error) { 304 if encryptedTLFCryptKeys.encryptedData.Version == 305 EncryptionSecretboxWithKeyNonce { 306 // Only blocks should have v2 encryption. 307 return nil, errors.WithStack( 308 InvalidEncryptionVer{encryptedTLFCryptKeys.encryptedData.Version}) 309 } 310 311 nonce, err := encryptedTLFCryptKeys.encryptedData.Nonce24() 312 if err != nil { 313 return nil, err 314 } 315 316 encodedKeys, err := decryptData( 317 encryptedTLFCryptKeys.encryptedData, key.Data(), nonce) 318 if err != nil { 319 return nil, err 320 } 321 322 var oldKeys []TLFCryptKey 323 err = codec.Decode(encodedKeys, &oldKeys) 324 if err != nil { 325 return nil, err 326 } 327 328 return oldKeys, nil 329 } 330 331 // EncryptedMerkleLeaf is an encrypted MerkleLeaf object. 332 type EncryptedMerkleLeaf struct { 333 encryptedData 334 } 335 336 // MakeEncryptedMerkleLeaf constructs an EncryptedMerkleLeaf. 337 func MakeEncryptedMerkleLeaf( 338 version EncryptionVer, data []byte, nonce *[24]byte) EncryptedMerkleLeaf { 339 return EncryptedMerkleLeaf{ 340 encryptedData{ 341 Version: version, 342 EncryptedData: data, 343 Nonce: nonce[:], 344 }, 345 } 346 } 347 348 // PrepareMerkleLeaf verifies the correctness of the given leaf, and 349 // returns its nonce. 350 func PrepareMerkleLeaf(encryptedMerkleLeaf EncryptedMerkleLeaf) ( 351 nonce [24]byte, err error) { 352 if encryptedMerkleLeaf.Version != EncryptionSecretbox { 353 return nonce, 354 errors.WithStack(UnknownEncryptionVer{ 355 Ver: encryptedMerkleLeaf.Version}) 356 } 357 358 if len(encryptedMerkleLeaf.Nonce) != len(nonce) { 359 return nonce, 360 errors.WithStack(InvalidNonceError{ 361 Nonce: encryptedMerkleLeaf.Nonce}) 362 } 363 copy(nonce[:], encryptedMerkleLeaf.Nonce) 364 return nonce, nil 365 } 366 367 // DecryptMerkleLeaf decrypts an EncryptedMerkleLeaf using the given 368 // private TLF key and ephemeral public key. 369 func DecryptMerkleLeaf( 370 privateKey TLFPrivateKey, publicKey TLFEphemeralPublicKey, 371 encryptedMerkleLeaf EncryptedMerkleLeaf) ([]byte, error) { 372 nonce, err := PrepareMerkleLeaf(encryptedMerkleLeaf) 373 if err != nil { 374 return nil, err 375 } 376 377 publicKeyData := publicKey.Data() 378 privateKeyData := privateKey.Data() 379 decryptedData, ok := box.Open(nil, encryptedMerkleLeaf.EncryptedData, 380 &nonce, &publicKeyData, &privateKeyData) 381 if !ok { 382 return nil, errors.WithStack( 383 libkb.DecryptionError{Cause: libkb.ErrorCause{Err: errors.New("Cannot open box")}}) 384 } 385 return decryptedData, nil 386 }