Funções do Keymaster

Esta página fornece detalhes para auxiliar os implementadores de Keymaster Hardware Abstraction Layers (HALs). 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 Keymaster Tags .

Diretrizes gerais de implementação

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

Parâmetros do ponteiro de entrada

Versão : 1, 2

Parâmetros de ponteiro de entrada que não são usados ​​para uma determinada chamada podem ser NULL . O chamador não é obrigado a fornecer espaços reservados. Por exemplo, alguns tipos e modos de chave podem não usar nenhum valor do argumento inParams para begin , portanto, o chamador pode definir inParams como NULL ou fornecer um conjunto de parâmetros vazio. Os chamadores também podem fornecer parâmetros não utilizados, e os métodos Keymaster não devem emitir erros.

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

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

Parâmetros do ponteiro de saída

Versão : 1, 2

Semelhante aos 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 encontrado como NULL , ele deverá retornar ErrorCode::OUTPUT_PARAMETER_NULL .

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

Uso indevido da API

Versão : 1, 2, 3

Há muitas maneiras pelas quais os chamadores 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 ou emitir um diagnóstico. Uso de chaves muito pequenas, especificação de parâmetros de entrada irrelevantes, reutilização de IVs ou nonces, geração de chaves sem propósitos (portanto inúteis) e similares não devem ser diagnosticados por implementações. Omissão de parâmetros obrigatórios, especificação de parâmetros obrigatórios inválidos e erros semelhantes devem ser diagnosticados.

É responsabilidade dos aplicativos, da estrutura 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 subjacente. O método não recebe argumentos e retorna quatro valores, todos booleanos:

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

Os únicos códigos de erro que este 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 preterida no Keymaster 3, pois essas informações estão disponíveis nos arquivos de propriedades do sistema e as implementações do fabricante lêem esses arquivos durante a inicialização.

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

Se a implementação do keymaster estiver em hardware seguro e a versão do SO e os valores de nível de 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 fornecer valores), esse método retornará KM_ERROR_INVALID_ARGUMENT e todos os outros métodos continuam retornando KM_ERROR_KEYMASTER_NOT_CONFIGURED .

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

addRngEntropia

Versão : 1, 2, 3

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

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

As implementações do Keymaster precisam misturar com segurança a entropia fornecida em seu pool, que também deve conter entropia gerada internamente a partir de um gerador de números aleatórios de hardware. A mistura deve ser tratada de forma que um invasor que tenha controle completo dos bits fornecidos por addRngEntropy ou dos bits gerados por hardware, mas não de ambos, não tenha nenhuma vantagem não desprezível na previsão dos bits gerados a partir do pool de entropia.

As implementações de Keymaster que tentam estimar a entropia em seu conjunto interno assumem 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.

gerar chave

Versão : 1, 2, 3

Esta 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 impossibilitam o uso de uma chave de 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 impor, a obrigação do hardware seguro limita-se a garantir que as autorizações inexequíveis associadas à chave não possam ser modificadas, de modo que cada chamada para getKeyCharacteristics retorne o valor original. Além disso, as características retornadas por generateKey alocam as autorizações corretamente entre as listas impostas por hardware e por software. Consulte getKeyCharacteristics para obter mais detalhes.

Os parâmetros fornecidos para generateKey dependem do tipo de chave que está sendo gerada. Esta seção resume as tags necessárias e opcionais para cada tipo de chave. Tag::ALGORITHM é 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 com suporte 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 RSA. Se omitido, o método retornará ErrorCode::INVALID_ARGUMENT . Os valores suportados são 3 e 65537. Os valores recomendados são todos os valores principais 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 retornará um erro se esses parâmetros forem omitidos.

  • Tag::PURPOSE especifica os propósitos permitidos. Todas as finalidades precisam ser suportadas por chaves RSA, em qualquer combinação.
  • Tag::DIGEST especifica algoritmos de resumo que podem ser usados ​​com a nova chave. As implementações que não oferecem suporte a todos os algoritmos de resumo precisam aceitar solicitações de geração de chave que incluem resumos não suportados. Os resumos não suportados devem 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 o resumo é executado em software. Em seguida, o hardware é chamado para executar 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 suportam todos os algoritmos de resumo precisam colocar PaddingMode::RSA_PSS e PaddingMode::RSA_OAEP na lista aplicada por software das principais características se algum algoritmo de resumo não suportado for especificado.

Chaves ECDSA

Apenas Tag::KEY_SIZE é necessário para gerar uma chave ECDSA. É usado para selecionar o grupo EC. Os valores suportados 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 geração.

Chaves AES

Apenas Tag::KEY_SIZE é necessário para gerar uma chave AES. Se omitido, o método retornará ErrorCode::UNSUPPORTED_KEY_SIZE . Os valores suportados 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 bloco com os quais a nova chave pode ser usada.
  • Tag::PADDING especifica os modos de preenchimento que podem ser usados. Isso é relevante apenas para os modos BCE e CBC.

Se o modo de bloco GCM for especificado, forneça o Tag::MIN_MAC_LENGTH . Se omitido, o método retornará ErrorCode::MISSING_MIN_MAC_LENGTH . O valor da tag é um múltiplo de 8 e 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 são múltiplos de 8 não são suportados. Todos os múltiplos de 8, de 64 a 512, são suportados. Valores maiores podem ser suportados.
  • Tag::MIN_MAC_LENGTH especifica o comprimento mínimo de MACs que podem ser gerados ou verificados com esta chave. O valor é um múltiplo de 8 e pelo menos 64.
  • Tag::DIGEST especifica o algoritmo de compilação para a chave. Exatamente um resumo é especificado, caso contrário, retorne ErrorCode::UNSUPPORTED_DIGEST . Se o resumo não for suportado pelo trustlet, retorne ErrorCode::UNSUPPORTED_DIGEST .

Caracteristicas principais

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

Etiqueta::ROLLBACK_RESISTANT .

Resistência à reversão

A resistência à reversão significa que, uma vez que uma chave é excluída com deleteKey ou deleteAllKeys , é garantido pelo hardware seguro que nunca mais poderá ser usado. As implementações sem resistência à reversão normalmente retornam material de chave gerado ou importado para o chamador como um blob de chave, um formulário criptografado e autenticado. Quando o keystore exclui o blob de chaves, a chave desaparece, mas um invasor que conseguiu recuperar o material da chave anteriormente pode restaurá-lo no dispositivo.

Uma chave é resistente à reversão se o hardware seguro garantir que as chaves excluídas não possam ser restauradas posteriormente. 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 é o Replay Protected Memory Blocks (RPMB). Como o número de chaves que podem ser criadas é essencialmente ilimitado e o armazenamento confiável usado para 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 adicionado às características-chave.

getKeyCharacteristics

Versão : 1, 2, 3

Esta 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: imposto por hardware e imposto por software. A descrição aqui se aplica igualmente às listas de características de chave retornadas por generateKey e importKey .

Se Tag::APPLICATION_ID foi fornecido durante a geração ou importação da chave, o mesmo valor será fornecido a este método no argumento clientId . Caso contrário, o método retornará ErrorCode::INVALID_KEY_BLOB . Da mesma forma, se Tag::APPLICATION_DATA foi fornecido durante a geração ou importação, o mesmo valor é fornecido para este 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 imposição de hardware ou de software é que, se o significado da tag for totalmente garantido por hardware seguro, ela será imposta por hardware. Caso contrário, é aplicado por software. Abaixo está uma lista de tags específicas cuja 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 estarão na lista de hardware obrigatório.
  • Os valores de Tag::DIGEST que são suportados pelo hardware seguro são colocados na lista de suporte de hardware. Os resumos não suportados vão para a lista com suporte por software.
  • Os valores de Tag::PADDING geralmente vão na lista de suporte de hardware, a menos que haja a possibilidade de que um modo de preenchimento específico precise ser executado por software. Nesse caso, eles vão para a lista aplicada por software. Essa possibilidade surge para chaves RSA que permitem preenchimento de PSS ou OAEP com algoritmos de resumo que não são suportados pelo hardware seguro.
  • Tag::USER_SECURE_ID e Tag::USER_AUTH_TYPE são aplicadas por hardware somente se a autenticação do usuário for aplicada por hardware. Para fazer isso, o trustlet Keymaster e o trustlet de autenticação relevante devem ser seguros e compartilhar uma chave HMAC secreta usada para assinar e validar tokens de autenticação. Consulte a página Autenticação para obter detalhes.
  • Tag::ACTIVE_DATETIME , Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME tags requerem acesso a um relógio de parede verificavelmente correto. O hardware mais seguro só tem acesso às informações de tempo fornecidas pelo sistema operacional 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 a hardware. Sua presença nessa lista é a maneira como as camadas superiores determinam que uma chave é suportada por hardware.

importKey

Versão : 1, 2, 3

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

Importa material de chave para o hardware Keymaster. Os parâmetros de definição de chave e as características de saída são tratados da mesma forma que para 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 for fornecido, o trustlet deduz os valores do material de chave fornecido e adiciona tags e valores apropriados às características da chave. Se os parâmetros forem fornecidos, o trustlet os validará em relação ao material da 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

Esta 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 Keymaster RSA ou EC.

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

deleteKey

Versão : 1, 2, 3

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

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

deleteAllKeys

Versão : 1, 2, 3

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

Exclui todas as chaves. Este método é opcional e só é implementado por módulos Keymaster que oferecem resistência à 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 permanentemente desabilitado depois que esse método for chamado, o atestado de ID não deverá ser implementado, caso em que esse método não fará nada e retornará ErrorCode::UNIMPLEMENTED . Se o atestado de ID for compatível, esse método precisará ser implementado e deverá desativar permanentemente todas as tentativas futuras de atestado de ID. O método pode ser chamado várias vezes. Se o atestado de ID já estiver permanentemente desabilitado, o método não fará nada e retornará ErrorCode::OK .

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

começar

Versão : 1, 2, 3

Inicia uma operação criptográfica, usando a chave especificada, para a finalidade especificada, com os parâmetros especificados (conforme apropriado) e retorna um identificador 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 tais operações, é incluído no campo de challenge do token de autenticação.

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

Se Tag::APPLICATION_ID ou Tag::APPLICATION_DATA foram especificados durante a geração ou importação da chave, as chamadas para begin incluirão essas tags com 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 impostas pelo trustlet se a implementação as colocar 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 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() deve 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 criptografia assimétrica ou operações de verificação.
  • Tag::ACTIVE_DATETIME só pode ser aplicada se uma fonte de hora UTC confiável estiver disponível. Se a data e 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 hora UTC confiável estiver disponível. Se a data e hora atuais forem posteriores ao valor da tag e a finalidade for KeyPurpose::ENCRYPT ENCRYPT ou KeyPurpose::SIGN , o método retornará ErrorCode::KEY_EXPIRED .
  • Tag::USAGE_EXPIRE_DATETIME só pode ser aplicada se uma fonte de hora UTC confiável estiver disponível. Se a data e hora atuais forem posteriores ao valor da tag e a finalidade for KeyPurpose::DECRYPT ou KeyPurpose::VERIFY , o método retornará ErrorCode::KEY_EXPIRED .
  • Tag::MIN_SECONDS_BETWEEN_OPS é comparado com um cronômetro relativo confiável que indica o último uso da chave. Se a hora do último uso mais o valor da tag for menor que a hora atual, o método retornará ErrorCode::KEY_RATE_LIMIT_EXCEEDED . Consulte a descrição da tag para obter detalhes importantes da implementação.
  • Tag::MAX_USES_PER_BOOT é comparado com um contador seguro que rastreia os usos da chave desde o tempo de inicialização. Se a contagem de usos anteriores exceder o valor da tag, o método retornará ErrorCode::KEY_MAX_OPS_EXCEEDED .
  • Tag::USER_SECURE_ID é aplicado por este método somente se a chave também tiver Tag::AUTH_TIMEOUT . Se a chave tiver ambos, esse método deve receber um Tag::AUTH_TOKEN válido em inParams . Para que o token de autenticação seja válido, todos os itens a seguir devem ser verdadeiros:
    • O campo HMAC valida 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 um 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 chamador especifique um nonce ou vetor de inicialização (IV). Se a chave não tiver essa tag, mas o chamador fornecer Tag::NONCE para esse método, ErrorCode::CALLER_NONCE_PROHIBITED será retornado.
  • Tag::BOOTLOADER_ONLY especifica que somente o bootloader pode usar a chave. Se esse método for chamado com uma chave somente do carregador de inicialização após a conclusão da execução do carregador de inicialização, ele retornará ErrorCode::INVALID_KEY_BLOB .

Chaves RSA

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

As operações de assinatura e verificação RSA precisam de um resumo, assim como as operações de criptografia e descriptografia RSA com modo de preenchimento OAEP. Para esses casos, o chamador 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 ENCRYPT e KeyPurpose::VERIFY ) são permitidas com resumo ou preenchimento não autorizados.

Com exceção de PaddingMode::NONE , todos os modos de preenchimento RSA são aplicáveis ​​apenas para determinadas finalidades. Especificamente, PaddingMode::RSA_PKCS1_1_5_SIGN e PaddingMode::RSA_PSS suportam apenas assinatura e verificação, enquanto PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT e PaddingMode::RSA_OAEP suportam apenas criptografia e descriptografia. O método retornará ErrorCode::UNSUPPORTED_PADDING_MODE se o modo especificado não oferecer suporte à finalidade especificada.

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

  • PaddingMode::NONE indica que uma operação RSA "raw" é executada. Se estiver assinando ou verificando, Digest::NONE é 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 construir uma estrutura de assinatura PKCS#1 v1.5 adequada, porque não pode adicionar a estrutura DigestInfo. Em vez disso, a implementação constrói 0x00 || 0x01 || PS || 0x00 || M , onde M é a mensagem fornecida e PS é a string de preenchimento. O tamanho da chave RSA deve ser pelo menos 11 bytes maior que a mensagem, caso contrário, o método retornará ErrorCode::INVALID_INPUT_LENGTH .
  • PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT o preenchimento não requer um resumo.
  • O preenchimento PaddingMode::RSA_PSS requer um resumo, que pode não ser Digest::NONE . Se Digest::NONE for especificado, o método retornará ErrorCode::INCOMPATIBLE_DIGEST . Além disso, o tamanho da chave RSA deve ser pelo menos 2 + D bytes maior que o tamanho de saída do resumo, onde D é o tamanho do resumo, em bytes. Caso contrário, o método retornará ErrorCode::INCOMPATIBLE_DIGEST . O tamanho do sal é D.
  • O preenchimento PaddingMode::RSA_OAEP requer um resumo, que pode não ser Digest::NONE . Se Digest::NONE for especificado, o método retornará ErrorCode::INCOMPATIBLE_DIGEST .

Chaves EC

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

As operações de chave privada ( 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, retorne ErrorCode::INCOMPATIBLE_DIGEST . As operações de chave pública ( KeyPurpose::VERIFY ) são permitidas com resumo ou preenchimento não autorizados.

Chaves AES

As operações da tecla AES especificam exatamente um modo de bloco e um modo de preenchimento 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 devem ser autorizados pela chave, caso contrário, o método retornará ErrorCode::INCOMPATIBLE_BLOCK_MODE ou ErrorCode::INCOMPATIBLE_PADDING_MODE .

Se o modo de bloco 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 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 preenchimento especificado deve 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 bloco for BlockMode::CBC , BlockMode::CTR ou BlockMode::GCM , é necessário um vetor de inicialização ou nonce. Na maioria dos casos, os chamadores não devem fornecer um IV ou nonce. Nesse caso, a implementação do Keymaster gera um IV aleatório ou nonce e o retorna via Tag::NONCE em outParams . CBC e CTR IVs são 16 bytes. GCM nonces são 12 bytes. Se as autorizações de chave contiverem Tag::CALLER_NONCE , o chamador poderá fornecer um IV/nonce com Tag::NONCE em inParams . Se um nonce for fornecido quando Tag::CALLER_NONCE não estiver autorizado, retorne ErrorCode::CALLER_NONCE_PROHIBITED . Se um nonce não for fornecido quando Tag::CALLER_NONCE for autorizado, gere um IV/nonce aleatório.

Chaves HMAC

As operações de chave HMAC especificam Tag::MAC_LENGTH em inParams . O valor especificado deve ser um múltiplo de 8 que não seja maior que o tamanho do resumo ou menor que o valor de Tag::MIN_MAC_LENGTH nas autorizações de chave. Para comprimentos 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 .

atualizar

Versão : 1, 2, 3

Fornece dados a serem processados ​​em uma operação contínua iniciada com begin . A operação é especificada pelo parâmetro operationHandle .

Para fornecer mais flexibilidade para manipulação de buffer, as implementações desse método têm a opção de consumir menos dados do que o fornecido. O chamador é responsável pelo 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 chamadores consideram isso um erro e abortam a operação.

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

Manipulação de erros

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

Aplicação de autorização

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

Neste caso, a chave requer 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 ao 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 chamador fornece o token de autenticação para cada chamada para atualização e conclusão . 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 , este método aceita que todo o bloco seja assinado ou verificado em uma única atualização. Pode não consumir apenas uma parte do bloco. No entanto, se o chamador optar por fornecer os dados em várias atualizações, esse método os aceitará. Se o chamador fornecer mais dados para assinar do que pode ser usado (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 que todo o bloco seja assinado ou verificado em uma única atualização. Este método não pode consumir apenas uma parte do bloco.

No entanto, se o chamador optar por fornecer os dados em várias atualizações, esse método os aceitará. Se o chamador fornecer mais dados para assinar do que pode ser usado, os dados serão truncados silenciosamente. (Isso difere do tratamento de dados em excesso fornecidos em operações RSA semelhantes. A razão para isso é a compatibilidade com clientes legados.)

Chaves AES

O modo AES GCM suporta "dados de autenticação associados", fornecidos por meio da 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 criptografar/descriptografar, mas as atualizações subsequentes podem não incluir dados associados. Se o chamador fornecer dados associados a uma chamada de atualização após uma chamada que inclua dados para criptografar/descriptografar, retorne ErrorCode::INVALID_TAG .

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

Finalizar

Versão : 1, 2, 3

Finishes an ongoing operation started with begin , processing all of the as-yet-unprocessed data provided by update (s).

This method is the last one called in an operation, so all processed data is returned.

Whether it completes successfully or returns an error, this method finalizes the operation and therefore invalidates the provided operation handle. Any future use of the handle, with this method or update or abort , returns ErrorCode::INVALID_OPERATION_HANDLE .

Signing operations return the signature as the output. Verification operations accept the signature in the signature parameter, and return no output.

Authorization enforcement

Key authorization enforcement is performed primarily in begin . The one exception is the case where the key has:

In this case, the key requires an authorization per operation, and the update method receives a Tag::AUTH_TOKEN in the inParams argument. HMAC verifies that the token is valid and contains a matching secure user ID, matches the key's Tag::USER_AUTH_TYPE , and contains the operation handle of the current operation in the challenge field. If these conditions aren't met, return ErrorCode::KEY_USER_NOT_AUTHENTICATED .

The caller provides the authentication token to every call to update and finish . The implementation need only validate the token once if it prefers.

RSA keys

Some additional requirements, depending on the padding mode:

  • PaddingMode::NONE . For unpadded signing and encryption operations, if the provided data is shorter than the key, the data is be zero-padded on the left before signing/encryption. If the data is the same length as the key, but numerically larger, return ErrorCode::INVALID_ARGUMENT . For verification and decryption operations, the data must be exactly as long as the key. Otherwise, return ErrorCode::INVALID_INPUT_LENGTH.
  • PaddingMode::RSA_PSS . For PSS-padded signature operations, the PSS salt is at least 20 bytes in length and randomly generated. The salt may be longer; the reference implementation uses maximally sized salt. The digest specified with Tag::DIGEST in inputParams on begin is used as the PSS digest algorithm, and SHA1 is used as the MGF1 digest algorithm.
  • PaddingMode::RSA_OAEP . The digest specified with Tag::DIGEST in inputParams on begin is used as the OAEP digest algorithm, and SHA1 is used as the MGF1 digest algorithm.

ECDSA keys

If the data provided for unpadded signing or verification is too long, truncate it.

AES keys

Some additional conditions, depending on block mode:

  • BlockMode::ECB or BlockMode::CBC . If padding is PaddingMode::NONE and the data length is not a multiple of the AES block size, return ErrorCode::INVALID_INPUT_LENGTH . If padding is PaddingMode::PKCS7 , pad the data per the PKCS#7 specification. Note that PKCS#7 recommends adding an additional padding block if the data is a multiple of the block length.
  • BlockMode::GCM . During encryption, after processing all plaintext, compute the tag ( Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption, process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, return ErrorCode::VERIFICATION_FAILED .

abort

Version : 1, 2, 3

Aborts the in-progress operation. After the call to abort, return ErrorCode::INVALID_OPERATION_HANDLE for any subsequent use of the provided operation handle with update , finish , or abort .

get_supported_algorithms

Version : 1

Returns the list of algorithms supported by the Keymaster hardware implementation. A software implementation returns an empty list; a hybrid implementation returns a list containing only the algorithms that are supported by hardware.

Keymaster 1 implementations support RSA, EC, AES and HMAC.

get_supported_block_modes

Version : 1

Returns the list of AES block modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

For RSA, EC and HMAC, which are not block ciphers, the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES encryption and decryption.

get_supported_padding_modes

Version : 1

Returns the list of padding modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

HMAC and EC have no notion of padding so the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE .

For RSA, Keymaster 1 implementations support:

  • Unpadded encryption, decryption, signing and verification. For unpadded encryption and signing, if the message is shorter than the public modulus, implementations must left-pad it with zeros. For unpadded decryption and verification, the input length must match the public modulus size.
  • PKCS#1 v1.5 encryption and signing padding modes
  • PSS with a minimum salt length of 20
  • OAEP

For AES in ECB and CBC modes, Keymaster 1 implementations support no padding and PKCS#7-padding. CTR and GCM modes support only no padding.

get_supported_digests

Version : 1

Returns the list of digest modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.

No AES modes support or require digesting, so the method returns an empty list for valid purposes.

Keymaster 1 implementations can implement a subset of the defined digests. Implementations provide SHA-256 and can provide MD5, SHA1, SHA-224, SHA-256, SHA384 and SHA512 (the full set of defined digests).

get_supported_import_formats

Version : 1

Returns the list of import formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster 1 implementations support the PKCS#8 format (without password protection) for importing RSA and EC key pairs, and support RAW import of AES and HMAC key material.

get_supported_export_formats

Version : 1

Returns the list of export formats supported by the Keymaster hardware implementation of a specified algorithm.

Keymaster1 implementations support the X.509 format for exporting RSA and EC public keys. Export of private keys or asymmetric keys is not supported.

Historical functions

Keymaster 0

The following functions belong to the original Keymaster 0 definition. They were present in Keymaster 1 struct keymaster1_device_t. However, in Keymaster 1.0 they were not implemented, and their function pointers were set to NULL.

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

Keymaster 1

The following functions belong to the Keymaster 1 definition, but were removed in Keymaster 2, along with the Keymaster 0 functions listed above.

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

Keymaster 2

The following functions belong to the Keymaster 2 definition, but were removed in Keymaster 3, along with the Keymaster 1 functions listed above.

  • configure