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
ePaddingMode::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, retorneErrorCode::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,
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
ouKeyPurpose::SIGN
, o método vai retornarErrorCode::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
ouKeyPurpose::VERIFY
, o método vai retornarErrorCode::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 serDigest::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 cria0x00 || 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 serDigest::NONE
. SeDigest::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 serDigest::NONE
. SeDigest::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:
- Um ou mais Tag::USER_SECURE_IDs e
- Não tem uma Tag::AUTH_TIMEOUT
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:
- um ou mais Tag::USER_SECURE_IDs e
- Não tem um Tag::AUTH_TIMEOUT
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, retorneErrorCode::INVALID_ARGUMENT
. Para operações de verificação e descriptografia, os dados precisam ser exatamente tão longos quanto a chave. Caso contrário, retorneErrorCode::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 eminputParams
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 eminputParams
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
ouBlockMode::CBC
. Se o padding forPaddingMode::NONE
e o comprimento dos dados não for múltiplo do tamanho do bloco AES, retorneErrorCode::INVALID_INPUT_LENGTH
. Se o preenchimento forPaddingMode::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, retorneErrorCode::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