AlexaClientSDK  3.0.0
A cross-platform, modular SDK for interacting with the Alexa Voice Service
Public Types | Public Member Functions | List of all members
alexaClientSDK::cryptoInterfaces::CryptoCodecInterface Class Referenceabstract

Crypto codec (cipher) interface. More...

#include <CryptoCodecInterface.h>

Inheritance diagram for alexaClientSDK::cryptoInterfaces::CryptoCodecInterface:
Inheritance graph
[legend]

Public Types

typedef std::vector< unsigned char > DataBlock
 Data block type. This type represents a byte array. More...
 
typedef std::vector< unsigned char > Key
 Key type. This type contains key bytes. More...
 
typedef std::vector< unsigned char > IV
 Initialization vector type. Initialization vector contains data to initialize codec state before encrypting or decrypting data. More...
 
typedef std::vector< unsigned char > Tag
 Tag vector type. Tag is used with AEAD mode of operation like with Galois/Counter mode. More...
 

Public Member Functions

virtual ~CryptoCodecInterface () noexcept=default
 Default destructor. More...
 
virtual bool init (const Key &key, const IV &iv) noexcept=0
 Initialize the codec. More...
 
virtual bool processAAD (const DataBlock &dataIn) noexcept=0
 Process AAD data block. More...
 
virtual bool processAAD (DataBlock::const_iterator dataInBegin, DataBlock::const_iterator dataInEnd) noexcept=0
 Process AAD data block range. More...
 
virtual bool process (const DataBlock &dataIn, DataBlock &dataOut) noexcept=0
 Encrypt or decrypt a data block. More...
 
virtual bool process (DataBlock::const_iterator dataInBegin, DataBlock::const_iterator dataInEnd, DataBlock &dataOut) noexcept=0
 Encrypt or decrypt a data block range. More...
 
virtual bool finalize (DataBlock &dataOut) noexcept=0
 Complete data processing. More...
 
virtual bool getTag (Tag &tag) noexcept=0
 Provides tag from authenticated encryption. More...
 
virtual bool setTag (const Tag &tag) noexcept=0
 Sets tag for authenticated decryption. More...
 

Detailed Description

Crypto codec (cipher) interface.

This interface provides functions to encrypt and decrypt the data, and behaviour depends on the way the interface is created. See CryptoFactoryInterface for details on this interface creation.


Using Encryption and Decryption without Authentication

For encryption without authentication, the algorithm takes key, initialization vector, and plaintext (unencrypted data) as inputs, and produces ciphertext (encrypted data) as output. Application must keep the key secret, while initialization vector can be stored or transferred along ciphertext.

For decryption without authentication, the algorithm takes key, initialization vector, and ciphertext (encrypted data) as inputs, and produces plaintext (unencrypted data) as output. When decrypting, key and initialization vector must match the ones, provided during decryption.

Codec must be initialized before use with a call to CryptoCodecInterface::init method. The data is encrypted or decrypted with subsequent calls to CryptoCodecInterface::process. Because the codec may cache some of the output inside internal buffers, the user must call CryptoCodecInterface::finalize method to get the output remainder.

auto codec = cryptoFactory->createEncoder(AlgorithmType::AES_256_CBC_PAD);
cipher->init(key, iv);
codec->encode(plaintext, &ciphertext);
codec->finalize(&ciphertext);

The interface allows processing of a continuous stream of data, broken into parts, as long as each part is mappable into one of supported "process" inputs.

cipher->init(key, iv);
// Encode data blocks
codec->process(plaintext1, ciphertext);
codec->process(plaintext2, ciphertext);
...
codec->process(plaintextN, ciphertext);
codec->finalize(&ciphertext);

The instance of this class can be re-initialized for reuse by calling init() method and supplying new key and IV. This method resets codec state and prepares it for encoding/decoding new data. Key and IV can have the same value or be different:

// Encode the data with a key and first IV.
cipher->init(key, iv1);
codec->process(plaintext1, ciphertext1);
...
codec->finalize(&ciphertext1);
// Reset the codec to re-encode data with the same key but different IV
codec->init(key, iv2)
codec->process(plaintext1, ciphertext2);
...
codec->finalize(&ciphertext2);

Using Authenticated Encryption and Authenticated Decryption (AEAD) Algorithms

Authenticated encryption

For authenticated encryption, the algorithm takes key, initialization vector, additional authenticated data (AAD) and plaintext (unencrypted data) as inputs, and produces ciphertext (encrypted data) and tag (also known as Message Authentication Code/MAC) as outputs.

Application must keep the key data secret, while initialization vector and tag can be stored or transferred along ciphertext. The best practice is not to store AAD but to compute it depending on domain scenario. For example, when encrypting property values, property key can be used as AAD, which would protect encrypted data from being reused for a property with a different name.

Overall, encryption process is similar to un-authenticated encryption, with the following differences:

After codec is initialized with init() method, additional data is provided with processAAD() calls before starting encryption with process() method calls. The tag is retrieved with getTag() call after finalize().

// Encrypt the data with a key and first IV.
cipher->init(key, iv1);
codec->processAAD(additionalAuthenticatedData);
...
// Start encrypting data
codec->process(plaintext1, ciphertext1);
...
codec->finalize(&ciphertext1);
// Retrieve tag
codec->getTag(tag);

Authenticated Decryption

For authenticated decryption, the algorithm takes key, initialization vector, additional authenticated data (AAD), tag (also known as Message Authentication Code/MAC), and ciphertext (encrypted data) as inputs, and produces plaintext (unencrypted data) as output.

Overall, decryption process is similar to un-authenticated decryption, with the following differences:

After codec is initialized with init() method, additional data is provided with processAAD() calls before starting decryption with process() method calls. The tag is set with setTag() call before finalize().

// Decrypt the data with a key and first IV.
cipher->init(key, iv1);
codec->processAAD(additionalAuthenticatedData);
...
// Start decrypting data
codec->process(plaintext1, ciphertext1);
...
// Set tag for verification
code->setTag(tag);
// Finalize the operation
codec->finalize(&ciphertext1);

Thread Safety

This interface is not thread safe and caller must ensure only one thread can make calls at any time.

Member Typedef Documentation

◆ DataBlock

Data block type. This type represents a byte array.

◆ IV

Initialization vector type. Initialization vector contains data to initialize codec state before encrypting or decrypting data.

◆ Key

Key type. This type contains key bytes.

◆ Tag

Tag vector type. Tag is used with AEAD mode of operation like with Galois/Counter mode.

Constructor & Destructor Documentation

◆ ~CryptoCodecInterface()

virtual alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::~CryptoCodecInterface ( )
virtualdefaultnoexcept

Default destructor.

Member Function Documentation

◆ finalize()

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::finalize ( DataBlock dataOut)
pure virtualnoexcept

Complete data processing.

Completes processing (encryption or decryption) of data. This method writes a final data block to dataOut if necessary. Finalize may or may not produce a final data block depending on codec state and encryption mode. For example, when block cipher is used without padding, this method never produces contents (it may still fail if previous input didn't match block boundary), but when PKCS#7 padding is used, this method may produce up to block size bytes of data.

When performing Authenticated Encryption, this method completes tag (MAC) computation and getTag() method shall be called after this method.

When performing Authenticated Decryption, setTag() method shall be called with a tag (MAC) and this method performs tag validation.

Parameters
[out]dataOutProcessed data. Method appends data to dataOut container.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec and dataOut are undefined, and the codec object must be re-initialized or discarded.
See also
getTag()
setTag()

◆ getTag()

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::getTag ( Tag tag)
pure virtualnoexcept

Provides tag from authenticated encryption.

This method returns a tag (known as Message Authentication Code/MAC) after authenticated encryption is completed with finalize() call. This method must be used with Authenticated Encryption Authenticated Decryption ciphers like AES-GCM, and cannot be used with non-AEAD algorithms. TThe method will fail if the codec algorithm is not from AEAD family.

Parameters
[out]tagTag value. Method appends a value to tag container.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec and tag are undefined, and the codec object must be re-initialized or discarded.
See also
setTag()
https://en.wikipedia.org/wiki/Message_authentication_code

◆ init()

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::init ( const Key key,
const IV iv 
)
pure virtualnoexcept

Initialize the codec.

Initializes (or re-initializes) codec with a given key and initialization vector. This method must be called before any processing can be done.

This method can be called to reset and re-initialize codec instance for reuse.

Parameters
[in]keyKey to use. The method will fail with an error if the size of the key doesn't correspond to cipher type.
[in]ivInitialization vector. The method will fail with an error if the size of IV doesn't correspond to cipher type.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec is undefined, and the object must be discarded.

◆ process() [1/2]

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::process ( const DataBlock dataIn,
DataBlock dataOut 
)
pure virtualnoexcept

Encrypt or decrypt a data block.

Processes (encrypts or decrypts) a data block. This method consumes a block of input data and optionally produces output data. Because cipher algorithms can cache some data internally, the size of output may not match size of input.

This method can be called any number of times after init has been performed and before calling finalize. If there is no more data to process, the user must call finalize() to get the final data block. The method will fail, if this method is called before init() or after finalize() calls.

When cipher is processing data, the output is appended to dataOut container. The caller should not make assumptions how many bytes will be appended, as the implementation may cache data internally.

Parameters
[in]dataInData to encrypt or decrypt. If the data container is empty, the method will do nothing and return true.
[out]dataOutProcessed data. Method appends data to dataOut container. The size of output may differ from the size of input.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec and dataOut are undefined, and the codec object must be re-initialized or discarded.

◆ process() [2/2]

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::process ( DataBlock::const_iterator  dataInBegin,
DataBlock::const_iterator  dataInEnd,
DataBlock dataOut 
)
pure virtualnoexcept

Encrypt or decrypt a data block range.

Processes (encrypts or decrypts) a data block range. This method consumes a block of input data and optionally produces output data. Because cipher algorithms can cache some data internally, the size of output may not match size of input.

This method can be called any number of times after init has been performed and before calling finalize. If there is no more data to process, the user must call finalize() to get the final data block. The method will fail, if this method is called before init() or after finalize() calls.

When cipher is processing data, the output is appended to dataOut container. The caller should not make assumptions how many bytes will be appended, as the implementation may cache data internally.

Parameters
[in]dataInBeginRange start. This parameter must be equal or less than dataInEnd. If the parameter is greater than dataInEnd the implementation does nothing and returns false.
[in]dataInEndRange end. This parameter must be equal or greater than dataInBegin. If the parameter is smaller than dataInBegin the implementation does nothing and returns false.
[out]dataOutProcessed data. Method appends (not replaces) data to dataOut container. The size of output may differ from the size of input.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec and dataOut are undefined, and the codec object must be re-initialized or discarded.

◆ processAAD() [1/2]

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::processAAD ( const DataBlock dataIn)
pure virtualnoexcept

Process AAD data block.

Processes Additional Authenticated Data block. AAD is used for Authenticated Encryption Authenticated Decryption algorithms like AES-GCM, and cannot be used with non-AEAD algorithms.

AEAD algorithms allow submission of arbitrary amount of AAD (including none), and this data affects algorithm output and tag value computation. When data is encrypted with AAD, the same AAD must be used for decryption.

AAD doesn't impact the output size of ciphertext when encrypting, nor the size of plaintext when decrypting. For data decryption the total submitted AAD input must match the one used for encryption. There is no difference if AAD is submitted all at once, or split into smaller chunks and submitted through a series of calls.

This method can be called any number of times after init() has been performed and before calling process(). If there is no more data to process, the user must call finalize() to get the final data block. The method will fail, if this method is called before init() or after process() or finalize() calls. The method will fail if the codec algorithm is not from AEAD family.

Parameters
[in]dataInAdditional authenticated data. If the data container is empty, the method will do nothing and return true.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec is undefined, and the codec object must be re-initialized or discarded.

◆ processAAD() [2/2]

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::processAAD ( DataBlock::const_iterator  dataInBegin,
DataBlock::const_iterator  dataInEnd 
)
pure virtualnoexcept

Process AAD data block range.

Processes Additional Authenticated Data block range. AAD is used for Authenticated Encryption Authenticated Decryption algorithms like AES-GCM, and cannot be used with non-AEAD algorithms.

AEAD algorithms allow submission of arbitrary amount of AAD (including none), and this data affects algorithm output and tag value computation. When data is encrypted with AAD, the same AAD must be used for decryption.

AAD doesn't impact the output size of ciphertext when encrypting, nor the size of plaintext when decrypting. For data decryption the total submitted AAD input must match the one used for encryption. There is no difference if AAD is submitted all at once, or split into smaller chunks and submitted through a series of calls.

This method can be called any number of times after init() has been performed and before calling process(). If there is no more data to process, the user must call finalize() to get the final data block. The method will fail, if this method is called before init() or after process() or finalize() calls. The method will fail if the codec algorithm is not from AEAD family.

Parameters
[in]dataInBeginRange start. This parameter must be equal or less than dataInEnd. If the parameter is greater than dataInEnd the implementation does nothing and returns false.
[in]dataInEndRange end. This parameter must be equal or greater than dataInBegin. If the parameter is smaller than dataInBegin the implementation does nothing and returns false.
Returns
True if operation has succeeded. If operation fails, false is returned, and the state of codec is undefined, and the codec object must be re-initialized or discarded.

◆ setTag()

virtual bool alexaClientSDK::cryptoInterfaces::CryptoCodecInterface::setTag ( const Tag tag)
pure virtualnoexcept

Sets tag for authenticated decryption.

This method provide a tag (known as Message Authentication Code/MAC) to authenticated decryption algorithm after all ciphertext is submitted with process() calls and before completing it with finalize() call. This method must be used with Authenticated Encryption Authenticated Decryption ciphers like AES-GCM, and cannot be used with non-AEAD algorithms. The method will fail if the codec algorithm is not from AEAD family.

Parameters
[in]tagTag value.
Returns
True if operation has succeeded. If operation fails, false is returned, the state of codec is undefined, and the codec object must be re-initialized or discarded.
See also
getTag()
https://en.wikipedia.org/wiki/Message_authentication_code

The documentation for this class was generated from the following file:

AlexaClientSDK 3.0.0 - Copyright 2016-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0