docs: def _generate_data_key(self, algorithm, encryption_context=None):
          """Generates data key and returns plaintext and ciphertext of key.
  
          :param algorithm: Algorithm on which to base data key
          :type algorithm: aws_encryption_sdk.identifiers.Algorithm
          :param dict encryption_context: Encryption context to pass to KMS
          :returns: Generated data key
          :rtype: aws_encryption_sdk.structures.DataKey
          """
          kms_params = {"KeyId": self._key_id, "NumberOfBytes": algorithm.kdf_input_len}
          if encryption_context is not None:
              kms_params["EncryptionContext"] = encryption_context
          if self.config.grant_tokens:
              kms_params["GrantTokens"] = self.config.grant_tokens
          # Catch any boto3 errors and normalize to expected EncryptKeyError
          try:
              response = self.config.client.generate_data_key(**kms_params)
              plaintext = response["Plaintext"]
              ciphertext = response["CiphertextBlob"]
              key_id = response["KeyId"]
          except (ClientError, KeyError):
              error_message = "Master Key {key_id} unable to generate data key".format(key_id=self._key_id)
              _LOGGER.exception(error_message)
              raise GenerateKeyError(error_message)
          return DataKey(
              key_provider=MasterKeyInfo(provider_id=self.provider_id, key_info=key_id),
              data_key=plaintext,
              encrypted_data_key=ciphertext,
          )