func (se *stateEncryptorImpl) Encrypt(msg []byte) ([]byte, error) { var b = make([]byte, 8) binary.BigEndian.PutUint64(b, se.counter) se.node.Debugf("Encrypting with counter [% x].", b) // se.log.Infof("Encrypting with txNonce ", utils.EncodeBase64(se.txNonce)) nonce := primitives.HMACTruncated(se.nonceStateKey, b, se.nonceSize) se.counter++ // Seal will append the output to the first argument; the usage // here appends the ciphertext to the nonce. The final parameter // is any additional data to be authenticated. out := se.gcmEnc.Seal(nonce, nonce, msg, se.invokeTxNonce) return append(se.invokeTxNonce, out...), nil }
func (se *queryStateEncryptor) Decrypt(raw []byte) ([]byte, error) { if len(raw) == 0 { // A nil ciphertext decrypts to nil return nil, nil } if len(raw) <= primitives.NonceSize { return nil, utils.ErrDecrypt } // raw consists of (txNonce, ct) txNonce := raw[:primitives.NonceSize] // se.log.Infof("Decrypting with txNonce ", utils.EncodeBase64(txNonce)) ct := raw[primitives.NonceSize:] nonce := make([]byte, se.nonceSize) copy(nonce, ct) key := primitives.HMACTruncated(se.deployTxKey, append([]byte{3}, txNonce...), primitives.AESKeyLength) // se.log.Infof("Decrypting with key ", utils.EncodeBase64(key)) c, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(c) if err != nil { return nil, err } se.nonceSize = se.gcmEnc.NonceSize() out, err := gcm.Open(nil, nonce, ct[se.nonceSize:], txNonce) if err != nil { return nil, utils.ErrDecrypt } return out, nil }
//getAttributeKey returns the attributeKey derived from the preK0 to the attributeName. func getAttributeKey(preK0 []byte, attributeName string) []byte { return primitives.HMACTruncated(preK0, []byte(attributeName), 32) }
func (validator *validatorImpl) getStateEncryptor1_2(deployTx, executeTx *obc.Transaction) (StateEncryptor, error) { // Check nonce if deployTx.Nonce == nil || len(deployTx.Nonce) == 0 { return nil, errors.New("Invalid deploy nonce.") } if executeTx.Nonce == nil || len(executeTx.Nonce) == 0 { return nil, errors.New("Invalid invoke nonce.") } // Check ChaincodeID if deployTx.ChaincodeID == nil { return nil, errors.New("Invalid deploy chaincodeID.") } if executeTx.ChaincodeID == nil { return nil, errors.New("Invalid execute chaincodeID.") } // Check that deployTx and executeTx refers to the same chaincode if !reflect.DeepEqual(deployTx.ChaincodeID, executeTx.ChaincodeID) { return nil, utils.ErrDifferentChaincodeID } // Check the confidentiality protocol version if deployTx.ConfidentialityProtocolVersion != executeTx.ConfidentialityProtocolVersion { return nil, utils.ErrDifferrentConfidentialityProtocolVersion } validator.Debugf("Parsing transaction. Type [%s]. Confidentiality Protocol Version [%s]", executeTx.Type.String(), executeTx.ConfidentialityProtocolVersion) deployStateKey, err := validator.getStateKeyFromTransaction(deployTx) if executeTx.Type == obc.Transaction_CHAINCODE_QUERY { validator.Debug("Parsing Query transaction...") executeStateKey, err := validator.getStateKeyFromTransaction(executeTx) // Compute deployTxKey key from the deploy transaction. This is used to decrypt the actual state // of the chaincode deployTxKey := primitives.HMAC(deployStateKey, deployTx.Nonce) // Compute the key used to encrypt the result of the query //queryKey := utils.HMACTruncated(executeStateKey, append([]byte{6}, executeTx.Nonce...), utils.AESKeyLength) // Init the state encryptor se := queryStateEncryptor{} err = se.init(validator.nodeImpl, executeStateKey, deployTxKey) if err != nil { return nil, err } return &se, nil } // Compute deployTxKey key from the deploy transaction deployTxKey := primitives.HMAC(deployStateKey, deployTx.Nonce) // Mask executeTx.Nonce executeTxNonce := primitives.HMACTruncated(deployTxKey, primitives.Hash(executeTx.Nonce), primitives.NonceSize) // Compute stateKey to encrypt the states and nonceStateKey to generates IVs. This // allows validators to reach consesus stateKey := primitives.HMACTruncated(deployTxKey, append([]byte{3}, executeTxNonce...), primitives.AESKeyLength) nonceStateKey := primitives.HMAC(deployTxKey, append([]byte{4}, executeTxNonce...)) // Init the state encryptor se := stateEncryptorImpl{} err = se.init(validator.nodeImpl, stateKey, nonceStateKey, deployTxKey, executeTxNonce) if err != nil { return nil, err } return &se, nil }