Funções do Keymaster

Esta página fornece detalhes para ajudar os implementadores de camadas de abstração de hardware (HALs) do Keymaster. Ele abrange cada função na API e em qual versão do Keymaster essa função está disponível e descreve a implementação padrão. Para tags, consulte a página Tags do Keymaster.

Diretrizes gerais de implementação

As diretrizes a seguir se aplicam a todas as funções na API.

Parâmetros de ponteiro de entrada

Versão: 1, 2

Os parâmetros do ponteiro de entrada que não são usados para uma determinada chamada podem ser NULL. O autor da chamada não precisa fornecer marcadores de posição. Por exemplo, alguns tipos e modos de chaves podem não usar valores do argumento inParams para início. Assim, o autor da chamada pode definir inParams como NULL ou fornecer um conjunto de parâmetros vazio. Os autores de chamadas também podem fornecer parâmetros não usados, e os métodos do Keymaster não devem emitir erros.

Se um parâmetro de entrada obrigatório for NULL, os métodos Keymaster vão retornar ErrorCode::UNEXPECTED_NULL_POINTER.

A partir do Keymaster 3, não há parâmetros de ponteiro. Todos os parâmetros são transmitidos por valor ou referências const.

Parâmetros do ponteiro de saída

Versão: 1, 2

Assim como os parâmetros de ponteiro de entrada, os parâmetros de ponteiro de saída não utilizados podem ser NULL. Se um método precisar retornar dados em um parâmetro de saída considerado NULL, ele retornará ErrorCode::OUTPUT_PARAMETER_NULL.

A partir do Keymaster 3, não há parâmetros de ponteiro. Todos os parâmetros são transmitidos por valor ou referências const.

uso indevido da API

Versão: 1, 2, 3

Há muitas maneiras pelas quais os autores da chamada podem fazer solicitações que não fazem sentido ou são tolas, mas não tecnicamente erradas. As implementações do Keymaster não precisam falhar nesses casos nem emitir diagnósticos. O uso de chaves muito pequenas, a especificação de parâmetros de entrada irrelevantes, a reutilização de IVs ou valores de uso único, a geração de chaves sem propósito (ou seja, inúteis) e assim por diante não devem ser diagnosticados pelas implementações. A omissão de parâmetros obrigatórios, a especificação de parâmetros obrigatórios inválidos e erros semelhantes precisam ser diagnosticados.

É responsabilidade dos apps, do framework e do keystore do Android garantir que as chamadas para os módulos do Keymaster sejam sensatas e úteis.

Funções

getHardwareFeatures

Versão: 3

O novo método getHardwareFeatures expõe aos clientes algumas características importantes do hardware seguro. O método não recebe argumentos e retorna quatro valores, todos booleanos:

  • isSecure será true se as chaves forem armazenadas em um hardware protegido (TEE etc.) e nunca saiam dele.
  • supportsEllipticCurve é true se o hardware oferece suporte à criptografia de curva elíptica com as curvas NIST (P-224, P-256, P-384 e P-521).
  • supportsSymmetricCryptography é true se o hardware oferece suporte à criptografia simétrica, incluindo AES e HMAC.
  • supportsAttestation é true se o hardware oferece suporte à geração de certificados de atestado de chave pública do Keymaster, assinados com uma chave injetada em um ambiente seguro.

Os únicos códigos de erro que esse método pode retornar são ErrorCode:OK, ErrorCode::KEYMASTER_NOT_CONFIGURED ou um dos códigos de erro que indicam uma falha na comunicação com o hardware seguro.

getHardwareFeatures()
    generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
              bool supportsAttestation, bool supportsAllDigests, string keymasterName,
              string keymasterAuthorName);

configurar

Versão: 2

Essa função foi introduzida no Keymaster 2 e descontinuada no Keymaster 3, já que essas informações estão disponíveis nos arquivos de propriedades do sistema, e as implementações do fabricante leem esses arquivos durante a inicialização.

Configura o keymaster. Esse método é chamado uma vez depois que o dispositivo é aberto e antes de ser usado. Ele é usado para fornecer KM_TAG_OS_VERSION e KM_TAG_OS_PATCHLEVEL ao keymaster. Até que esse método seja chamado, todos os outros métodos retornam KM_ERROR_KEYMASTER_NOT_CONFIGURED. Os valores fornecidos por esse método são aceitos pelo keymaster apenas uma vez por inicialização. As chamadas posteriores retornam KM_ERROR_OK, mas não fazem nada.

Se a implementação do keymaster estiver em um hardware seguro e os valores da versão do SO e do patch fornecidos não corresponderem aos valores fornecidos ao hardware seguro pelo carregador de inicialização (ou se o carregador de inicialização não tiver fornecido valores), esse método retornará KM_ERROR_INVALID_ARGUMENT, e todos os outros métodos continuarão retornando KM_ERROR_KEYMASTER_NOT_CONFIGURED.

keymaster_error_t (*configure)(const struct keymaster2_device* dev,
                               const keymaster_key_param_set_t* params);

addRngEntropy

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como add_rng_entropy e renomeada no Keymaster 3.

Adiciona a entropia fornecida pelo autor da chamada ao pool usado pela implementação do Keymaster 1 para gerar números aleatórios, chaves, IVs etc.

As implementações do Keymaster precisam misturar com segurança a entropia fornecida no pool, que também precisa conter entropia gerada internamente por um gerador de números aleatórios de hardware. A mistura precisa ser processada para que um invasor que tenha controle total dos bits fornecidos pelo addRngEntropy ou dos bits gerados por hardware, mas não ambos, não tenha vantagem não insignificante na previsão dos bits gerados pelo pool de entropia.

As implementações do Keymaster que tentam estimar a entropia no pool interno presumem que os dados fornecidos por addRngEntropy não contêm entropia. As implementações do Keymaster podem retornar ErrorCode::INVALID_INPUT_LENGTH se receberem mais de 2 KiB de dados em uma única chamada.

generateKey

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como generate_key e renomeada no Keymaster 3.

Gera uma nova chave criptográfica, especificando as autorizações associadas, que são permanentemente vinculadas à chave. As implementações do Keymaster tornam impossível usar uma chave de qualquer forma inconsistente com as autorizações especificadas no momento da geração. Com relação às autorizações que o hardware seguro não pode aplicar, a obrigação dele é limitada a garantir que as autorizações inexequíveis associadas à chave não possam ser modificadas, para que cada chamada para getKeyCharacteristics retorne o valor original. Além disso, as características retornadas por generateKey alocam autorizações corretamente entre as listas aplicadas por hardware e software. Consulte getKeyCharacteristics para mais detalhes.

Os parâmetros fornecidos a generateKey dependem do tipo de chave gerada. Esta seção resume as tags necessárias e opcionais para cada tipo de chave. Tag::ALGORITMO é sempre necessário para especificar o tipo.

Chaves RSA

Os parâmetros a seguir são necessários para gerar uma Chave RSA.

  • Tag::KEY_SIZE especifica o tamanho do módulo público, em bits. Se omitido, o método retornará ErrorCode::UNSUPPORTED_KEY_SIZE. Os valores aceitos são 1024, 2048, 3072 e 4096. Os valores recomendados são todos os tamanhos de chave que são múltiplos de 8.
  • Tag::RSA_PUBLIC_EXPONENT especifica o valor do expoente público do RSA. Se omitido, o método retorna ErrorCode::INVALID_ARGUMENT. Os valores aceitos são 3 e 65537. Os valores recomendados são todos os valores primos até 2^64.

Os parâmetros a seguir não são necessários para gerar uma chave RSA, mas criar uma chave RSA sem eles produz uma chave inutilizável. No entanto, a função generateKey não vai retornar um erro se esses parâmetros forem omitidos.

  • Tag::PURPOSE especifica as finalidades permitidas. Todas as finalidades precisam ser compatíveis com chaves RSA, em qualquer combinação.
  • Tag::DIGEST especifica algoritmos de resumo que podem ser usados com a chave nova. As implementações que não são compatíveis com todos os algoritmos de resumo precisam aceitar solicitações de geração de chaves que incluam resumos sem suporte. Os resumos não compatíveis precisam ser colocados na lista "aplicada por software" nas características de chave retornadas. Isso ocorre porque a chave pode ser usada com esses outros resumos, mas a digestão é realizada no software. Em seguida, o hardware é chamado para realizar a operação com Digest::NONE.
  • Tag::PADDING especifica os modos de preenchimento que podem ser usados com a nova chave. As implementações que não oferecem suporte a todos os algoritmos de resumo precisam colocar PaddingMode::RSA_PSS e PaddingMode::RSA_OAEP na lista de características de chaves imposta pelo software se algum algoritmo de resumo sem suporte for especificado.

Chaves ECDSA

Somente Tag::KEY_SIZE é necessário para gerar uma chave ECDSA. Ele é usado para selecionar o grupo de EC. Os valores aceitos são 224, 256, 384 e 521, que indicam as curvas NIST p-224, p-256, p-384 e p521, respectivamente.

Tag::DIGEST também é necessário para uma chave ECDSA útil, mas não é necessário para a geração.

Chaves AES

Somente Tag::KEY_SIZE é necessário para gerar uma chave AES. Se omitido, o método retorna ErrorCode::UNSUPPORTED_KEY_SIZE. Os valores aceitos são 128 e 256, com suporte opcional para chaves AES de 192 bits.

Os parâmetros a seguir são particularmente relevantes para chaves AES, mas não são necessários para gerar uma:

  • Tag::BLOCK_MODE especifica os modos de bloqueio com que a nova chave pode ser usada.
  • Tag::PADDING especifica os modos de preenchimento que podem ser usados. Isso só é relevante para os modos ECB e CBC.

Se o modo de bloqueio do GCM for especificado, forneça a Tag::MIN_MAC_LENGTH. Se omitido, o método retorna ErrorCode::MISSING_MIN_MAC_LENGTH. O valor da tag é um múltiplo de 8 e está entre 96 e 128.

Chaves HMAC

Os seguintes parâmetros são necessários para a geração de chave HMAC:

  • Tag::KEY_SIZE especifica o tamanho da chave em bits. Valores menores que 64 e valores que não sejam múltiplos de 8 não são aceitos. Todos os múltiplos de 8, de 64 a 512, são compatíveis. Valores maiores podem ser aceitos.
  • Tag::MIN_MAC_LENGTH especifica o comprimento mínimo de MACs que podem ser gerados ou verificados com essa chave. O valor é um múltiplo de 8 e pelo menos 64.
  • Tag::DIGEST especifica o algoritmo de resumo da chave. Exatamente um resumo é especificado. Caso contrário, retorna ErrorCode::UNSUPPORTED_DIGEST. Se o resumo não for compatível com o trustlet, retorne ErrorCode::UNSUPPORTED_DIGEST.

Principais características

Se o argumento de características não for NULL, generateKey vai retornar as características da chave recém-gerada divididas adequadamente em listas aplicadas por hardware e software. Consulte getKeyCharacteristics para ver uma descrição de quais características entram em cada lista. As características retornadas incluem todos os parâmetros especificados para a geração de chaves, exceto Tag::APPLICATION_ID e Tag::APPLICATION_DATA. Se essas tags forem incluídas nos parâmetros de chave, elas serão removidas das características retornadas para que não seja possível encontrar os valores delas ao examinar o blob de chave retornado. No entanto, eles são vinculados criptograficamente ao blob de chaves. Portanto, se os valores corretos não forem fornecidos quando a chave for usada, o uso falhará. Da mesma forma, Tag::ROOT_OF_TRUST é vinculado criptograficamente à chave, mas não pode ser especificado durante a criação ou importação de chaves e nunca é retornado.

Além das tags fornecidas, o trustlet também adiciona Tag::ORIGIN, com o valor KeyOrigin::GENERATED, e, se a chave for resistente a reversão,

Tag::ROLLBACK_RESISTANT.

Resistência a reversão

A resistência a reversão significa que, depois que uma chave é excluída com deleteKey ou deleteAllKeys, o hardware seguro garante que ela nunca mais será usada. Implementações sem resistência a reversão normalmente retornam o material de chave gerado ou importado para o autor da chamada como um blob de chave, um formulário criptografado e autenticado. Quando o keystore exclui o blob de chave, a chave desaparece, mas um invasor que conseguiu recuperar o material principal pode restaurá-lo no dispositivo.

Uma chave é resistente a reversão se o hardware seguro garante que as chaves excluídas não possam ser restauradas mais tarde. Isso geralmente é feito armazenando metadados de chave adicionais em um local confiável que não pode ser manipulado por um invasor. Em dispositivos móveis, o mecanismo usado para isso geralmente é blocos de memória protegidos contra repetição (RPMB, na sigla em inglês). Como o número de chaves que podem ser criadas é essencialmente ilimitado e o armazenamento confiável usado para a resistência à reversão pode ser limitado em tamanho, esse método precisa ser bem-sucedido, mesmo que a resistência à reversão não possa ser fornecida para a nova chave. Nesse caso, Tag::ROLLBACK_RESISTANT não deve ser adicionada às principais características.

getKeyCharacteristics

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como get_key_characteristics e renomeada no Keymaster 3.

Retorna parâmetros e autorizações associados à chave fornecida, divididos em dois conjuntos: aplicados por hardware e por software. A descrição aplicada aqui também se aplica às listas de características principais retornadas por generateKey e importKey.

Se Tag::APPLICATION_ID foi fornecido durante a geração ou importação de chaves, o mesmo valor será fornecido para esse método no argumento clientId. Caso contrário, o método retorna ErrorCode::INVALID_KEY_BLOB. Da mesma forma, se Tag::APPLICATION_DATA foi fornecido durante a geração ou importação, o mesmo valor será fornecido para esse método no argumento appData.

As características retornadas por esse método descrevem completamente o tipo e o uso da chave especificada.

A regra geral para decidir se uma determinada tag pertence à lista de hardware ou de software é que, se o significado da tag é totalmente garantido por hardware seguro, ela é aplicada por hardware. Caso contrário, o software será aplicado. Confira abaixo uma lista de tags específicas em que a alocação correta pode não ser clara:

  • Tag::ALGORITHM, Tag::KEY_SIZE e Tag::RSA_PUBLIC_EXPONENT são propriedades intrínsecas da chave. Para qualquer chave protegida por hardware, essas tags estão na lista de hardware.
  • Os valores Tag::DIGEST que têm suporte do hardware seguro são colocados na lista de suporte do hardware. Os resumos sem suporte vão para a lista de suporte de software.
  • Os valores de Tag::PADDING geralmente vão para a lista de suporte de hardware, a menos que haja a possibilidade de que um modo de preenchimento específico precise ser executado pelo software. Nesse caso, elas vão para a lista aplicada pelo software. Essa possibilidade surge para chaves RSA que permitem o preenchimento PSS ou OAEP com algoritmos de resumo que não têm suporte do hardware seguro.
  • Tag::USER_SECURE_ID e Tag::USER_AUTH_TYPE são aplicados pelo hardware somente se a autenticação do usuário for aplicada pelo hardware. Para fazer isso, o trustlet do Keymaster e o trustlet de autenticação relevante precisam ser seguros e compartilhar uma chave HMAC secreta usada para assinar e validar tokens de autenticação. Consulte a página Autenticação para mais detalhes.
  • As tags Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME exigem acesso a um relógio de parede comprovadamente correto. A maioria dos hardwares seguros só tem acesso às informações de tempo fornecidas pelo SO não seguro, o que significa que as tags são aplicadas por software.
  • Tag::ORIGIN está sempre na lista de hardware para chaves vinculadas ao hardware. A presença dela nessa lista é a maneira como as camadas mais altas determinam que uma chave é protegida por hardware.

importKey

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como import_key e renomeada no Keymaster 3.

Importa o material da chave para o hardware do Keymaster. Os parâmetros de definição de chave e as características de saída são processados da mesma forma que em generateKey, com as seguintes exceções:

  • Tag::KEY_SIZE e Tag::RSA_PUBLIC_EXPONENT (somente para chaves RSA) não são necessários nos parâmetros de entrada. Se não forem fornecidos, o trustlet deduz os valores do material de chave fornecido e adiciona tags e valores apropriados às características principais. Se os parâmetros forem fornecidos, o trustlet os valida em relação ao material de chave. Em caso de incompatibilidade, o método retorna ErrorCode::IMPORT_PARAMETER_MISMATCH.
  • A Tag::ORIGIN retornada tem o mesmo valor que KeyOrigin::IMPORTED.

exportKey

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como export_key e renomeada no Keymaster 3.

Exporta uma chave pública de um par de chaves RSA ou EC do Keymaster.

Se Tag::APPLICATION_ID foi fornecido durante a geração ou importação de chaves, o mesmo valor será fornecido para esse método no argumento clientId. Caso contrário, o método retorna ErrorCode::INVALID_KEY_BLOB. Da mesma forma, se Tag::APPLICATION_DATA for fornecido durante a geração ou importação, o mesmo valor será fornecido para esse método no argumento appData.

deleteKey

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como delete_key e renomeada no Keymaster 3.

Exclui a chave fornecida. Esse método é opcional e só é implementado por módulos Keymaster que oferecem resistência a reversão.

deleteAllKeys

Versão: 1, 2, 3

Essa função foi introduzida no Keymaster 1 como delete_all_keys e renomeada no Keymaster 3.

Exclui todas as chaves. Esse método é opcional e só é implementado por módulos Keymaster que oferecem resistência a reversão.

destroyAttestationIds

Versão: 3

O método destroyAttestationIds() é usado para desativar permanentemente o novo recurso de atestado de ID (opcional, mas altamente recomendado). Se o TEE não tiver como garantir que o atestado de ID seja desativado permanentemente após a chamada desse método, o atestado de ID não poderá ser implementado. Nesse caso, esse método não faz nada e retorna ErrorCode::UNIMPLEMENTED. Se a atestação de documento tiver suporte, esse método precisa ser implementado e desabilitar permanentemente todas as tentativas futuras de atestação de documento. O método pode ser chamado quantas vezes forem necessárias. Se o atestado de ID já estiver desativado permanentemente, o método não vai fazer nada e retornará ErrorCode::OK.

Os únicos códigos de erro que esse método pode retornar são ErrorCode::UNIMPLEMENTED (se o atestado de identificação não tiver suporte), ErrorCode:OK, ErrorCode::KEYMASTER_NOT_CONFIGURED ou um dos códigos de erro que indicam uma falha na comunicação com o hardware seguro.

begin

Versão: 1, 2, 3

Inicia uma operação criptográfica usando a chave especificada para o propósito específico, com os parâmetros especificados (conforme apropriado) e retorna um handle de operação que é usado com update e finish para concluir a operação. O identificador de operação também é usado como token de "desafio" em operações autenticadas e, para essas operações, está incluído no campo challenge do token de autenticação.

Uma implementação do Keymaster oferece suporte a pelo menos 16 operações simultâneas. O keystore usa até 15, deixando um para o vold usar para criptografia de senha. Quando o Keystore tem 15 operações em andamento (begin foi chamado, mas finish ou abort não foram chamados) e recebe uma solicitação para iniciar a 16ª, ele chama abort na operação menos usada recentemente para reduzir o número de operações ativas para 14 antes de chamar begin para iniciar a operação recém-solicitada.

Se Tag::APPLICATION_ID ou Tag::APPLICATION_DATA for especificada durante a geração ou importação de chaves, as chamadas para begin incluirão os valores originalmente especificados no argumento inParams para esse método.

Aplicação de autorização

Durante esse método, as seguintes autorizações de chave são aplicadas pelo trustlet se a implementação as colocou nas características "aplicadas por hardware" e se a operação não for uma operação de chave pública. As operações de chave pública, ou seja, KeyPurpose::ENCRYPT e KeyPurpose::VERIFY, com chaves RSA ou EC, podem ser bem-sucedidas mesmo que os requisitos de autorização não sejam atendidos.

  • Tag::PURPOSE: a finalidade especificada na chamada begin() precisa corresponder a uma das finalidades nas autorizações de chave, a menos que a operação solicitada seja uma operação de chave pública. Se a finalidade especificada não corresponder e a operação não for uma operação de chave pública, begin retornará ErrorCode::UNSUPPORTED_PURPOSE. As operações de chave pública são operações de criptografia ou verificação assimétricas.
  • Tag::ACTIVE_DATETIME só pode ser aplicada se uma origem de tempo UTC confiável estiver disponível. Se a data e a hora atuais forem anteriores ao valor da tag, o método retornará ErrorCode::KEY_NOT_YET_VALID.
  • Tag::ORIGINATION_EXPIRE_DATETIME só pode ser aplicada se uma fonte de tempo UTC confiável estiver disponível. Se a data e a hora atuais forem posteriores ao valor da tag e a finalidade for KeyPurpose::ENCRYPT ou KeyPurpose::SIGN, o método vai retornar ErrorCode::KEY_EXPIRED.
  • A Tag::USAGE_EXPIRE_DATETIME só pode ser aplicada se uma fonte de horário UTC confiável estiver disponível. Se a data e a hora atuais forem posteriores ao valor da tag e a finalidade for KeyPurpose::DECRYPT ou KeyPurpose::VERIFY, o método vai retornar ErrorCode::KEY_EXPIRED.
  • Tag::MIN_SECONDS_BETWEEN_OPS é comparada a um timer relativo confiável, que indica o último uso da chave. Se o horário do último uso mais o valor da tag for menor que o horário atual, o método retornará ErrorCode::KEY_RATE_LIMIT_EXCEEDED. Consulte a descrição da tag para conferir detalhes importantes sobre a implementação.
  • Tag::MAX_USES_PER_BOOT é comparado a um contador seguro que rastreia os usos da chave desde o momento da inicialização. Se a contagem de usos anteriores exceder o valor da tag, o método vai retornar ErrorCode::KEY_MAX_OPS_EXCEEDED.
  • Tag::USER_SECURE_ID é aplicado por esse método somente se a chave também tiver Tag::AUTH_TIMEOUT. Se a chave tiver os dois, esse método precisará receber um Tag::AUTH_TOKEN válido em inParams. Para que o token de autenticação seja válido, todos os itens a seguir precisam ser verdadeiros:
    • O campo HMAC é validado corretamente.
    • Pelo menos um dos valores Tag::USER_SECURE_ID da chave corresponde a pelo menos um dos valores de ID seguro no token.
    • A chave tem uma Tag::USER_AUTH_TYPE que corresponde ao tipo de autenticação no token.

    Se alguma dessas condições não for atendida, o método retornará ErrorCode::KEY_USER_NOT_AUTHENTICATED.

  • Tag::CALLER_NONCE permite que o autor da chamada especifique um valor de uso único ou um vetor de inicialização (IV). Se a chave não tiver essa tag, mas o autor da chamada tiver fornecido Tag::NONCE para esse método, ErrorCode::CALLER_NONCE_PROHIBITED será retornado.
  • Tag::BOOTLOADER_ONLY especifica que apenas o carregador de inicialização pode usar a chave. Se esse método for chamado com uma chave exclusiva do carregador de inicialização após a conclusão da execução do carregador, ele retornará ErrorCode::INVALID_KEY_BLOB.

Chaves RSA

Todas as operações da Chave RSA especificam exatamente um modo de padding em inParams. Se não for especificado ou for especificado mais de uma vez, o método vai retornar ErrorCode::UNSUPPORTED_PADDING_MODE.

As operações de assinatura e verificação do RSA precisam de um resumo, assim como as operações de criptografia e descriptografia do RSA com o modo de preenchimento do OAEP. Nesses casos, o autor da chamada especifica exatamente um resumo em inParams. Se não for especificado ou especificado mais de uma vez, o método retornará ErrorCode::UNSUPPORTED_DIGEST.

As operações de chave privada (KeyPurpose::DECYPT e KeyPurpose::SIGN) precisam de autorização de resumo e preenchimento, o que significa que as autorizações de chave precisam conter os valores especificados. Caso contrário, o método retornará ErrorCode::INCOMPATIBLE_DIGEST ou ErrorCode::INCOMPATIBLE_PADDING, conforme apropriado. As operações de chave pública (KeyPurpose::ENCRYPT e KeyPurpose::VERIFY) são permitidas com resumo ou preenchimento não autorizado.

Com exceção de PaddingMode::NONE, todos os modos de preenchimento de RSA são aplicáveis apenas para determinados fins. Especificamente, PaddingMode::RSA_PKCS1_1_5_SIGN e PaddingMode::RSA_PSS têm suporte apenas para assinatura e verificação, enquanto PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT e PaddingMode::RSA_OAEP têm suporte apenas para criptografia e descriptografia. O método retorna ErrorCode::UNSUPPORTED_PADDING_MODE se o modo especificado não for compatível com a finalidade especificada.

Há algumas interações importantes entre os modos de preenchimento e os resumos:

  • PaddingMode::NONE indica que uma operação RSA "bruta" foi realizada. Se estiver assinando ou verificando, Digest::NONE será especificado para o resumo. Nenhum resumo é necessário para criptografia ou descriptografia sem preenchimento.
  • O preenchimento PaddingMode::RSA_PKCS1_1_5_SIGN requer um resumo. O resumo pode ser Digest::NONE. Nesse caso, a implementação do Keymaster não pode criar uma estrutura de assinatura PKCS#1 v1.5 adequada, porque não é possível adicionar a estrutura DigestInfo. Em vez disso, a implementação cria 0x00 || 0x01 || PS || 0x00 || M, em que M é a mensagem fornecida e PS é a string de preenchimento. O tamanho da Chave RSA precisa ser pelo menos 11 bytes maior que a mensagem. Caso contrário, o método retornará ErrorCode::INVALID_INPUT_LENGTH.
  • O padding de PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT não requer um resumo.
  • O padding PaddingMode::RSA_PSS requer um resumo, que não pode ser Digest::NONE. Se Digest::NONE for especificado, o método retornará ErrorCode::INCOMPATIBLE_DIGEST. Além disso, o tamanho da chave RSA precisa ser pelo menos 2 + D bytes maior que o tamanho de saída do resumo, em que D é o tamanho do resumo, em bytes. Caso contrário, o método retornará ErrorCode::INCOMPATIBLE_DIGEST. O tamanho do sal é D.
  • O padding PaddingMode::RSA_OAEP requer um resumo, que não pode ser Digest::NONE. Se Digest::NONE for especificado, o método retornará ErrorCode::INCOMPATIBLE_DIGEST.

Chaves EC

As operações da chave EC especificam exatamente um modo de padding em inParams. Se não for especificado ou especificado mais de uma vez, o método vai retornar ErrorCode::UNSUPPORTED_PADDING_MODE.

As operações de chaves privadas (KeyPurpose::SIGN) precisam de autorização de resumo e preenchimento, o que significa que as autorizações de chave precisam conter os valores especificados. Caso contrário, retorna ErrorCode::INCOMPATIBLE_DIGEST. Operações de chave pública (KeyPurpose::VERIFY) são permitidas com resumo ou preenchimento não autorizado.

Chaves AES

As operações de chave AES especificam exatamente um modo de bloco e um modo de padding em inParams. Se um dos valores não for especificado ou for especificado mais de uma vez, retorne ErrorCode::UNSUPPORTED_BLOCK_MODE ou ErrorCode::UNSUPPORTED_PADDING_MODE. Os modos especificados precisam ser autorizados pela chave. Caso contrário, o método retornará ErrorCode::INCOMPATIBLE_BLOCK_MODE ou ErrorCode::INCOMPATIBLE_PADDING_MODE.

Se o modo de bloqueio for BlockMode::GCM, inParams especificar Tag::MAC_LENGTH e o valor especificado for um múltiplo de 8 que não seja maior que 128 ou menor que o valor de Tag::MIN_MAC_LENGTH nas autorizações de chave. Para comprimentos de MAC maiores que 128 ou não múltiplos de 8, retorne ErrorCode::UNSUPPORTED_MAC_LENGTH. Para valores menores que o comprimento mínimo da chave, retorne ErrorCode::INVALID_MAC_LENGTH.

Se o modo de bloco for BlockMode::GCM ou BlockMode::CTR, o modo de padding especificado precisa ser PaddingMode::NONE. Para BlockMode::ECB ou BlockMode::CBC, o modo pode ser PaddingMode::NONE ou PaddingMode::PKCS7. Se o modo de preenchimento não atender a essas condições, retorne ErrorCode::INCOMPATIBLE_PADDING_MODE.

Se o modo de bloqueio for BlockMode::CBC, BlockMode::CTR ou BlockMode::GCM, será necessário um vetor de inicialização ou um valor de uso único. Na maioria dos casos, os autores de chamadas não precisam fornecer um IV ou um valor de uso único. Nesse caso, a implementação do Keymaster gera um IV ou valor de uso único aleatório e o retorna com Tag::NONCE em outParams. Os IVs CBC e CTR têm 16 bytes. Os valores de uso único do GCM são de 12 bytes. Se as autorizações de chave contiverem Tag::CALLER_NONCE, o autor da chamada poderá fornecer um IV ou nonce com Tag::NONCE em inParams. Se um valor de uso único for fornecido quando Tag::CALLER_NONCE não estiver autorizado, retorne ErrorCode::CALLER_NONCE_PROHIBITED. Se um valor de uso único não for fornecido quando Tag::CALLER_NONCE estiver autorizado, gere um IV/valor de uso único aleatório.

Chaves HMAC

As operações de chave HMAC especificam Tag::MAC_LENGTH em inParams. O valor especificado precisa ser um múltiplo de 8 que não seja maior que o comprimento do resumo ou menor que o valor de Tag::MIN_MAC_LENGTH nas autorizações de chave. Para comprimentos de MAC maiores que o comprimento do resumo ou não múltiplos de 8, retorne ErrorCode::UNSUPPORTED_MAC_LENGTH. Para valores menores que o comprimento mínimo da chave, retorne ErrorCode::INVALID_MAC_LENGTH.

update

Versão: 1, 2, 3

Fornece dados para processamento em uma operação em andamento iniciada com begin. A operação é especificada pelo parâmetro operationHandle.

Para oferecer mais flexibilidade ao processamento de buffer, as implementações desse método têm a opção de consumir menos dados do que o fornecido. O autor da chamada é responsável por um loop para alimentar o restante dos dados nas chamadas subsequentes. A quantidade de entrada consumida é retornada no parâmetro inputConsumed. As implementações sempre consomem pelo menos um byte, a menos que a operação não possa aceitar mais. Se mais de zero bytes forem fornecidos e zero bytes forem consumidos, os autores da chamada vão considerar isso como um erro e interromper a operação.

As implementações também podem escolher quantos dados retornar, como resultado da atualização. Isso só é relevante para operações de criptografia e descriptografia porque a assinatura e a verificação não retornam dados até a conclusão. Retorne os dados o mais cedo possível, em vez de armazená-los em buffer.

Tratamento de erros

Se esse método retornar um código de erro diferente de ErrorCode::OK, a operação será abortada e o identificador de operação será invalidado. Qualquer uso futuro do identificador, com esse método, finish ou abort, retorna ErrorCode::INVALID_OPERATION_HANDLE.

Aplicação da autorização

A aplicação de autorização de chave é realizada principalmente em begin. A única exceção é o caso em que a chave tem:

Nesse caso, a chave exige uma autorização por operação, e o método de atualização recebe um Tag::AUTH_TOKEN no argumento inParams. O HMAC verifica se o token é válido e contém um ID de usuário seguro correspondente, corresponde à Tag::USER_AUTH_TYPE da chave e contém o identificador da operação atual no campo de desafio. Se essas condições não forem atendidas, retorne ErrorCode::KEY_USER_NOT_AUTHENTICATED.

O autor da chamada fornece o token de autenticação para cada chamada para atualizar e concluir. A implementação só precisa validar o token uma vez, se preferir.

Chaves RSA

Para operações de assinatura e verificação com Digest::NONE, esse método aceita o bloco inteiro para ser assinado ou verificado em uma única atualização. Ele não pode consumir apenas uma parte do bloco. No entanto, se o autor da chamada escolher fornecer os dados em várias atualizações, esse método vai aceitar. Se o autor da chamada fornecer mais dados para assinar do que podem ser usados (o comprimento dos dados excede o tamanho da chave RSA), retorne ErrorCode::INVALID_INPUT_LENGTH.

Chaves ECDSA

Para operações de assinatura e verificação com Digest::NONE, este método aceita o bloco inteiro para ser assinado ou verificado em uma única atualização. Esse método não pode consumir apenas uma parte do bloco.

No entanto, se o autor da chamada optar por fornecer os dados em várias atualizações, esse método vai aceitar. Se o autor da chamada fornecer mais dados para assinar do que podem ser usados, os dados serão truncados silenciosamente. Isso é diferente do processamento de dados em excesso fornecidos em operações RSA semelhantes. O motivo disso é a compatibilidade com clientes legados.)

Chaves AES

O modo AES GCM oferece suporte a "dados de autenticação associados" fornecidos pela tag Tag::ASSOCIATED_DATA no argumento inParams. Os dados associados podem ser fornecidos em chamadas repetidas (importante se os dados forem muito grandes para serem enviados em um único bloco), mas sempre precedem os dados a serem criptografados ou descriptografados. Uma chamada de atualização pode receber dados associados e dados para criptografia/descriptografia, mas as atualizações subsequentes não podem incluir dados associados. Se o autor da chamada fornecer dados associados a uma chamada de atualização após uma chamada que inclui dados para criptografia/descriptografia, retorne ErrorCode::INVALID_TAG.

Para a criptografia GCM, a tag é anexada ao texto criptografado por finish. Durante a descriptografia, os últimos bytes Tag::MAC_LENGTH dos dados fornecidos para a última chamada de atualização são a tag. Como uma determinada invocação de update não pode saber se é a última invocação, ela processa tudo, exceto a duração da tag, e armazena em buffer os possíveis dados da tag durante o finish.

concluir

Versão: 1, 2, 3

Conclui uma operação em andamento iniciada com begin, processando todos os dados ainda não processados fornecidos por update.

Esse método é o último chamado em uma operação. Portanto, todos os dados processados são retornados.

Independentemente de ser concluído com êxito ou retornar um erro, esse método finaliza a operação e, portanto, invalida a operação fornecida. Qualquer uso futuro do identificador, com esse método ou update ou abort, retorna ErrorCode::INVALID_OPERATION_HANDLE.

As operações de assinatura retornam a assinatura como a saída. As operações de verificação aceitam a assinatura no parâmetro signature e não retornam nenhuma saída.

Aplicação de autorização

A aplicação da autorização de chaves é realizada principalmente no início. A única exceção é o caso em que a chave tem:

Nesse caso, a chave requer uma autorização por operação, e o método de atualização recebe uma Tag::AUTH_TOKEN no argumento inParams. O HMAC verifica se o token é válido e contém um ID de usuário seguro correspondente, corresponde à Tag::USER_AUTH_TYPE da chave e contém o identificador de operação da operação atual no campo de desafio. Se essas condições não forem atendidas, retorne ErrorCode::KEY_USER_NOT_AUTHENTICATED.

O autor da chamada fornece o token de autenticação para cada chamada para atualizar e concluir. A implementação só precisa validar o token uma vez, se preferir.

Chaves RSA

Alguns requisitos adicionais, dependendo do modo de preenchimento:

  • PaddingMode::NONE. Para operações de assinatura e criptografia sem preenchimento, se os dados fornecidos forem menores que a chave, eles serão preenchidos com zero à esquerda antes da assinatura/criptografia. Se os dados tiverem o mesmo comprimento que a chave, mas numericamente maiores, retorne ErrorCode::INVALID_ARGUMENT. Para operações de verificação e descriptografia, os dados precisam ser exatamente tão longos quanto a chave. Caso contrário, retorne ErrorCode::INVALID_INPUT_LENGTH..
  • PaddingMode::RSA_PSS. Para operações de assinatura com preenchimento PSS, o sal PSS é do tamanho do resumo de mensagem e gerado aleatoriamente. O resumo especificado com Tag::DIGEST em inputParams em begin é usado como o algoritmo de resumo PSS e como o algoritmo de resumo MGF1.
  • PaddingMode::RSA_OAEP. O resumo especificado com Tag::DIGEST em inputParams em begin é usado como o algoritmo de resumo OAEP, e o SHA1 é usado como o algoritmo de resumo MGF1.

Chaves ECDSA

Se os dados fornecidos para assinatura ou verificação sem preenchimento forem muito longos, corte-os.

Chaves AES

Algumas condições adicionais, dependendo do modo de bloqueio:

  • BlockMode::ECB ou BlockMode::CBC. Se o padding for PaddingMode::NONE e o comprimento dos dados não for múltiplo do tamanho do bloco AES, retorne ErrorCode::INVALID_INPUT_LENGTH. Se o preenchimento for PaddingMode::PKCS7, preencha os dados de acordo com a especificação PKCS#7. O PKCS#7 recomenda adicionar um bloco de preenchimento extra se os dados forem um múltiplo do comprimento do bloco.
  • BlockMode::GCM. Durante a criptografia, após processar todo o texto simples, calcule a tag (bytes Tag::MAC_LENGTH) e anexe-a ao texto criptografado retornado. Durante a descriptografia, processe os últimos bytes Tag::MAC_LENGTH como a tag. Se a verificação de tags falhar, retorne ErrorCode::VERIFICATION_FAILED.

abortar

Versão: 1, 2, 3

Aborta a operação em andamento. Após a chamada para abortar, retorne ErrorCode::INVALID_OPERATION_HANDLE para qualquer uso subsequente do identificador de operação fornecido com update, finish ou abort.

get_supported_algorithms

Versão: 1

Retorna a lista de algoritmos com suporte à implementação de hardware do Keymaster. Uma implementação de software retorna uma lista vazia, e uma implementação híbrida retorna uma lista que contém apenas os algoritmos com suporte do hardware.

As implementações do Keymaster 1 oferecem suporte a RSA, EC, AES e HMAC.

get_supported_block_modes

Versão: 1

Retorna a lista de modos de bloco AES aceitos pela implementação de hardware do Keymaster para um algoritmo e finalidade especificados.

Para RSA, EC e HMAC, que não são cifras de bloco, o método retorna uma lista vazia para todas as finalidades válidas. Propósitos inválidos devem fazer com que o método retorne ErrorCode::INVALID_PURPOSE.

As implementações do Keymaster 1 oferecem suporte a ECB, CBC, CTR e GCM para criptografia e descriptografia AES.

get_supported_padding_modes

Versão: 1

Retorna a lista de modos de preenchimento com suporte da implementação de hardware do Keymaster para um algoritmo e finalidade especificados.

HMAC e EC não têm noção de preenchimento, portanto, o método retorna uma lista vazia para todos os fins válidos. Propósitos inválidos devem fazer com que o método retorne ErrorCode::INVALID_PURPOSE.

Para RSA, as implementações do Keymaster 1 oferecem suporte a:

  • Criptografia, descriptografia, assinatura e verificação sem padding. Para criptografia e assinatura sem preenchimento, se a mensagem for menor que o módulo público, as implementações precisarão preencher à esquerda com zeros. Para descriptografia e verificação sem padding, o comprimento da entrada precisa corresponder ao tamanho do módulo público.
  • Modos de criptografia e padding de assinatura PKCS#1 v1.5
  • PSS com comprimento mínimo de 20 para o sal
  • OAEP

Para AES nos modos ECB e CBC, as implementações do Keymaster 1 oferecem suporte a padding e padding PKCS#7. Os modos CTR e GCM só oferecem suporte a padding.

get_supported_digests

Versão: 1

Retorna a lista de modos de resumo aceitos pela implementação de hardware do Keymaster para um algoritmo e uma finalidade especificados.

Nenhum modo AES oferece suporte ou exige digestão. Portanto, o método retorna uma lista vazia para fins válidos.

As implementações do Keymaster 1 podem implementar um subconjunto dos resumos definidos. As implementações fornecem SHA-256 e podem fornecer MD5, SHA1, SHA-224, SHA-256, SHA384 e SHA512 (o conjunto completo de resumos definidos).

get_supported_import_formats

Versão: 1

Retorna a lista de formatos de importação compatíveis com a implementação de hardware do Keymaster de um algoritmo especificado.

As implementações do Keymaster 1 oferecem suporte ao formato PKCS#8 (sem proteção de senha) para importar pares de chaves RSA e EC e oferecem suporte à importação RAW de materiais de chaves AES e HMAC.

get_supported_export_formats

Versão: 1

Retorna a lista de formatos de exportação aceitos pela implementação de hardware do Keymaster de um algoritmo especificado.

As implementações do Keymaster1 oferecem suporte ao formato X.509 para exportar chaves públicas RSA e EC. Não é possível exportar chaves privadas ou assimétricas.

Funções históricas

Keymaster 0

As funções a seguir pertencem à definição original do Keymaster 0. Eles estavam presentes na struct keymaster1_device_t do Keymaster 1. No entanto, no Keymaster 1.0, eles não foram implementados, e os ponteiros de função foram definidos como NULL.

  • generate_keypair
  • import_keypair
  • get_keypair_public
  • delete_keypair
  • delete_all
  • sign_data
  • Verify_data

Keymaster 1

As funções a seguir pertencem à definição do Keymaster 1, mas foram removidas no Keymaster 2, junto com as funções do Keymaster 0 listadas acima.

  • get_supported_algorithms
  • get_supported_block_modes
  • get_supported_padding_modes
  • get_supported_digests
  • get_supported_import_formats
  • get_supported_export_formats

Keymaster 2

As funções a seguir pertencem à definição do Keymaster 2, mas foram removidas no Keymaster 3, junto com as funções do Keymaster 1 listadas acima.

  • configure