github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/crypto_common.go (about) 1 // Copyright 2016 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 libkbfs 6 7 import ( 8 "crypto/rand" 9 10 "github.com/keybase/client/go/kbfs/data" 11 "github.com/keybase/client/go/kbfs/kbfsblock" 12 "github.com/keybase/client/go/kbfs/kbfscodec" 13 "github.com/keybase/client/go/kbfs/kbfscrypto" 14 "github.com/keybase/client/go/kbfs/kbfsmd" 15 "github.com/keybase/client/go/kbfs/tlf" 16 "github.com/pkg/errors" 17 "golang.org/x/crypto/nacl/box" 18 ) 19 20 // CryptoCommon contains many of the function implementations need for 21 // the Crypto interface, which can be reused by other implementations. 22 type CryptoCommon struct { 23 codec kbfscodec.Codec 24 blockCryptVersioner blockCryptVersioner 25 } 26 27 var _ cryptoPure = (*CryptoCommon)(nil) 28 29 // MakeCryptoCommon returns a default CryptoCommon object. 30 func MakeCryptoCommon( 31 codec kbfscodec.Codec, 32 blockCryptVersioner blockCryptVersioner) CryptoCommon { 33 return CryptoCommon{codec, blockCryptVersioner} 34 } 35 36 // MakeRandomTlfID implements the Crypto interface for CryptoCommon. 37 func (c CryptoCommon) MakeRandomTlfID(t tlf.Type) (tlf.ID, error) { 38 return tlf.MakeRandomID(t) 39 } 40 41 // MakeRandomBranchID implements the Crypto interface for CryptoCommon. 42 func (c CryptoCommon) MakeRandomBranchID() (kbfsmd.BranchID, error) { 43 return kbfsmd.MakeRandomBranchID() 44 } 45 46 // MakeTemporaryBlockID implements the Crypto interface for CryptoCommon. 47 func (c CryptoCommon) MakeTemporaryBlockID() (kbfsblock.ID, error) { 48 return kbfsblock.MakeTemporaryID() 49 } 50 51 // MakeBlockRefNonce implements the Crypto interface for CryptoCommon. 52 func (c CryptoCommon) MakeBlockRefNonce() (nonce kbfsblock.RefNonce, err error) { 53 return kbfsblock.MakeRefNonce() 54 } 55 56 // MakeRandomBlockCryptKeyServerHalf implements the Crypto interface 57 // for CryptoCommon. 58 func (c CryptoCommon) MakeRandomBlockCryptKeyServerHalf() ( 59 kbfscrypto.BlockCryptKeyServerHalf, error) { 60 return kbfscrypto.MakeRandomBlockCryptKeyServerHalf() 61 } 62 63 // MakeRandomTLFEphemeralKeys implements the Crypto interface for 64 // CryptoCommon. 65 func (c CryptoCommon) MakeRandomTLFEphemeralKeys() ( 66 kbfscrypto.TLFEphemeralPublicKey, kbfscrypto.TLFEphemeralPrivateKey, 67 error) { 68 return kbfscrypto.MakeRandomTLFEphemeralKeys() 69 } 70 71 // MakeRandomTLFKeys implements the Crypto interface for CryptoCommon. 72 func (c CryptoCommon) MakeRandomTLFKeys() (kbfscrypto.TLFPublicKey, 73 kbfscrypto.TLFPrivateKey, kbfscrypto.TLFCryptKey, error) { 74 publicKey, privateKey, err := box.GenerateKey(rand.Reader) 75 if err != nil { 76 return kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{}, 77 kbfscrypto.TLFCryptKey{}, errors.WithStack(err) 78 } 79 80 pubKey := kbfscrypto.MakeTLFPublicKey(*publicKey) 81 privKey := kbfscrypto.MakeTLFPrivateKey(*privateKey) 82 83 cryptKey, err := kbfscrypto.MakeRandomTLFCryptKey() 84 if err != nil { 85 return kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{}, 86 kbfscrypto.TLFCryptKey{}, err 87 } 88 89 return pubKey, privKey, cryptKey, nil 90 } 91 92 // EncryptPrivateMetadata implements the Crypto interface for CryptoCommon. 93 func (c CryptoCommon) EncryptPrivateMetadata( 94 pmd PrivateMetadata, key kbfscrypto.TLFCryptKey) ( 95 encryptedPmd kbfscrypto.EncryptedPrivateMetadata, err error) { 96 encodedPmd, err := c.codec.Encode(pmd) 97 if err != nil { 98 return kbfscrypto.EncryptedPrivateMetadata{}, err 99 } 100 101 return kbfscrypto.EncryptEncodedPrivateMetadata(encodedPmd, key) 102 } 103 104 // DecryptPrivateMetadata implements the Crypto interface for CryptoCommon. 105 func (c CryptoCommon) DecryptPrivateMetadata( 106 encryptedPmd kbfscrypto.EncryptedPrivateMetadata, key kbfscrypto.TLFCryptKey) ( 107 PrivateMetadata, error) { 108 encodedPrivateMetadata, err := kbfscrypto.DecryptPrivateMetadata( 109 encryptedPmd, key) 110 if err != nil { 111 return PrivateMetadata{}, err 112 } 113 114 var pmd PrivateMetadata 115 err = c.codec.Decode(encodedPrivateMetadata, &pmd) 116 if err != nil { 117 return PrivateMetadata{}, err 118 } 119 120 return pmd, nil 121 } 122 123 // EncryptBlock implements the Crypto interface for CryptoCommon. 124 func (c CryptoCommon) EncryptBlock( 125 block data.Block, tlfCryptKey kbfscrypto.TLFCryptKey, 126 blockServerHalf kbfscrypto.BlockCryptKeyServerHalf) ( 127 plainSize int, encryptedBlock kbfscrypto.EncryptedBlock, err error) { 128 encodedBlock, err := c.codec.Encode(block) 129 if err != nil { 130 return -1, kbfscrypto.EncryptedBlock{}, err 131 } 132 133 paddedBlock, err := kbfscrypto.PadBlock(encodedBlock) 134 if err != nil { 135 return -1, kbfscrypto.EncryptedBlock{}, err 136 } 137 138 encryptedBlock, err = 139 kbfscrypto.EncryptPaddedEncodedBlock( 140 paddedBlock, tlfCryptKey, blockServerHalf, 141 c.blockCryptVersioner.BlockCryptVersion()) 142 if err != nil { 143 return -1, kbfscrypto.EncryptedBlock{}, err 144 } 145 146 plainSize = len(encodedBlock) 147 return plainSize, encryptedBlock, nil 148 } 149 150 // DecryptBlock implements the Crypto interface for CryptoCommon. 151 func (c CryptoCommon) DecryptBlock( 152 encryptedBlock kbfscrypto.EncryptedBlock, 153 tlfCryptKey kbfscrypto.TLFCryptKey, 154 blockServerHalf kbfscrypto.BlockCryptKeyServerHalf, block data.Block) error { 155 var paddedBlock []byte 156 paddedBlock, err := kbfscrypto.DecryptBlock( 157 encryptedBlock, tlfCryptKey, blockServerHalf) 158 if err != nil { 159 return err 160 } 161 162 encodedBlock, err := kbfscrypto.DepadBlock(paddedBlock) 163 if err != nil { 164 return err 165 } 166 167 err = c.codec.Decode(encodedBlock, &block) 168 if err != nil { 169 return errors.WithStack(BlockDecodeError{err}) 170 } 171 return nil 172 }