En esta página, se proporcionan detalles para ayudar a los implementadores de las capas de abstracción de hardware (HAL) de Keymaster. Se abarca cada función de la API y en qué versión de Keymaster está disponible esa función, y se describe la implementación predeterminada. Para obtener información sobre las etiquetas, consulta la página Etiquetas de Keymaster.
Lineamientos generales de implementación
Los siguientes lineamientos se aplican a todas las funciones de la API.
Parámetros de puntero de entrada
Versión: 1, 2
Los parámetros de puntero de entrada que no se usan para una llamada determinada pueden ser NULL
. No es necesario que el llamador proporcione marcadores de posición.
Por ejemplo, es posible que algunos tipos y modos de clave no usen ningún valor del argumento inParams
para comenzar, por lo que el llamador podría establecer inParams
en NULL
o proporcionar un conjunto de parámetros vacío. Los emisores también pueden proporcionar parámetros sin usar, y los métodos de Keymaster no deben generar errores.
Si un parámetro de entrada obligatorio es NULL, los métodos de Keymaster deben mostrar ErrorCode::UNEXPECTED_NULL_POINTER
.
A partir de Keymaster 3, no hay parámetros de puntero. Todos los parámetros se pasan por valor o referencias const.
Parámetros del puntero de salida
Versión: 1, 2
Al igual que los parámetros del puntero de entrada, los parámetros del puntero de salida sin usar pueden ser NULL
. Si un método necesita mostrar datos en un parámetro de salida que se encuentra como NULL
, debe mostrar ErrorCode::OUTPUT_PARAMETER_NULL
.
A partir de Keymaster 3, no hay parámetros de puntero. Todos los parámetros se pasan mediante valores o referencias de constante.
Uso inadecuado de la API
Versión: 1, 2, 3
Los llamadores pueden realizar solicitudes que no tienen sentido o son tontas, pero que no son técnicamente incorrectas. Las implementaciones de Keymaster no son obligatorias para fallar en esos casos o emitir un diagnóstico. Las implementaciones no deben diagnosticar el uso de claves demasiado pequeñas, la especificación de parámetros de entrada irrelevantes, la reutilización de IVs o nonces, la generación de claves sin ningún propósito (por lo tanto, inútiles) y similares. Se deben diagnosticar la omisión de parámetros obligatorios, la especificación de parámetros obligatorios no válidos y errores similares.
Es responsabilidad de las apps, el framework y Android Keystore garantizar que las llamadas a los módulos de Keymaster sean razonables y útiles.
Funciones
getHardwareFeatures
Versión: 3
El nuevo método getHardwareFeatures
expone a los clientes algunas características importantes del hardware seguro subyacente.
El método no toma argumentos y muestra cuatro valores, todos booleanos:
isSecure
estrue
si las claves se almacenan en hardware seguro (TEE, etc.) y nunca salen de él.supportsEllipticCurve
estrue
si el hardware admite la criptografía de curva elíptica con las curvas NIST (P-224, P-256, P-384 y P-521).supportsSymmetricCryptography
estrue
si el hardware admite criptografía simétrica, incluidos AES y HMAC.supportsAttestation
estrue
si el hardware admite la generación de certificados de certificación de claves públicas de Keymaster, firmados con una clave insertada en un entorno seguro.
Los únicos códigos de error que puede mostrar este método son ErrorCode:OK
, ErrorCode::KEYMASTER_NOT_CONFIGURED
o uno de los códigos de error que indican que no se pudo establecer una comunicación con el hardware seguro.
getHardwareFeatures() generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, bool supportsAttestation, bool supportsAllDigests, string keymasterName, string keymasterAuthorName);
Configurar
Versión: 2
Esta función se introdujo en Keymaster 2 y dejó de estar disponible en Keymaster 3, ya que esta información está disponible en los archivos de propiedades del sistema, y las implementaciones del fabricante leen esos archivos durante el inicio.
Configura Keymaster. Se llama a este método una vez después de que se abre el dispositivo y antes de que se use. Se usa para proporcionar KM_TAG_OS_VERSION y KM_TAG_OS_PATCHLEVEL a Keymaster. Hasta que se llame a este método, todos los demás métodos mostrarán KM_ERROR_KEYMASTER_NOT_CONFIGURED
. Keymaster solo acepta los valores que proporciona este método una vez por inicio. Las llamadas posteriores muestran KM_ERROR_OK
, pero no hacen nada.
Si la implementación de Keymaster está en hardware seguro y los valores de nivel de parche y versión del SO proporcionados no coinciden con los valores que el bootloader proporcionó al hardware seguro (o si el bootloader no proporcionó valores), este método muestra KM_ERROR_INVALID_ARGUMENT
y todos los demás métodos siguen mostrando KM_ERROR_KEYMASTER_NOT_CONFIGURED
.
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
addRngEntropy
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como add_rng_entropy
y se le cambió el nombre en Keymaster 3.
Agrega la entropía proporcionada por el llamador al grupo que usa la implementación de Keymaster 1 para generar números aleatorios, claves, IVs, etcétera.
Las implementaciones de Keymaster deben combinar de forma segura la entropía proporcionada en su grupo, que también debe contener entropía generada de forma interna a partir de un generador de números aleatorios de hardware.
La combinación se debe controlar de modo que un atacante que tenga control completo de los bits proporcionados por addRngEntropy
o de los bits generados por hardware, pero no de ambos, no tenga una ventaja insignificante en la predicción de los bits generados a partir del grupo de entropía.
Las implementaciones de Keymaster que intentan estimar la entropía en su grupo interno suponen que los datos que proporciona addRngEntropy
no contienen entropía. Las implementaciones de Keymaster pueden mostrar ErrorCode::INVALID_INPUT_LENGTH
si se les proporciona más de 2 KiB de datos en una sola llamada.
generateKey
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como generate_key
y se le cambió el nombre en Keymaster 3.
Genera una nueva clave criptográfica, que especifica las autorizaciones asociadas, que están vinculadas de forma permanente a la clave. Las implementaciones de Keymaster hacen que sea imposible usar una clave de manera incoherente con las autorizaciones especificadas en el momento de la generación. Con respecto a las autorizaciones que el hardware seguro no puede aplicar, su obligación se limita a garantizar que las autorizaciones inaplicables asociadas con la clave no se puedan modificar, de modo que cada llamada a getKeyCharacteristics muestre el valor original. Además, las características que muestra generateKey
asignan autorizaciones correctamente entre las listas de hardware y software. Consulta getKeyCharacteristics para obtener más detalles.
Los parámetros proporcionados a generateKey
dependen del tipo de clave que se genera. En esta sección, se resumen las etiquetas necesarias y opcionales para
cada tipo de clave. Tag::ALGORITHM siempre es necesario para especificar el tipo.
Claves RSA
Los siguientes parámetros son necesarios para generar una clave RSA.
- Tag::KEY_SIZE especifica el tamaño del módulo público en bits. Si se omite, el método muestra
ErrorCode::UNSUPPORTED_KEY_SIZE
. Los valores admitidos son 1024, 2048, 3072 y 4096. Los valores recomendados son todos los tamaños de clave que son múltiplos de 8. - Tag::RSA_PUBLIC_EXPONENT especifica el valor del exponente público de RSA. Si se omite, el método muestra
ErrorCode::INVALID_ARGUMENT
. Los valores admitidos son 3 y 65,537. Los valores recomendados son todos los valores primos hasta 2^64.
Los siguientes parámetros no son necesarios para generar una clave RSA, pero si creas una clave RSA sin ellos, se produce una clave que no se puede usar. Sin embargo, la función generateKey
no muestra un error si se omiten estos parámetros.
- Tag::PURPOSE especifica los fines permitidos. Todos los fines deben ser compatibles con las claves RSA, en cualquier combinación.
- Tag::DIGEST especifica los algoritmos de resumen que se pueden usar con la clave nueva. Las implementaciones que no admiten todos los algoritmos de resumen deben aceptar solicitudes de generación de claves que incluyan resúmenes no admitidos. Los resúmenes no admitidos deben colocarse en la lista "aplicada por software" en las características de clave que se muestran.
Esto se debe a que la clave se puede usar con esos otros resúmenes, pero la digestión se realiza en software. Luego, se llama al hardware para realizar la operación con
Digest::NONE
. - Tag::PADDING especifica los modos de relleno que se pueden usar con la clave nueva. Las implementaciones que no admiten todos los algoritmos de resumen deben colocar
PaddingMode::RSA_PSS
yPaddingMode::RSA_OAEP
en la lista de características de clave que se aplica de forma forzosa por software si se especifican algoritmos de resumen no compatibles.
Claves ECDSA
Solo Tag::KEY_SIZE es necesario para generar una clave ECDSA. Se usa para seleccionar el grupo de EC. Los valores admitidos son 224, 256, 384 y 521, que indican las curvas p-224, p-256, p-384 y p521 de NIST, respectivamente.
Tag::DIGEST también es necesario para una clave ECDSA útil, pero no es obligatorio para la generación.
Claves AES
Solo Tag::KEY_SIZE es necesario para generar una clave AES. Si se omite, el método muestra ErrorCode::UNSUPPORTED_KEY_SIZE
. Los valores admitidos son 128 y 256, con compatibilidad opcional para claves AES de 192 bits.
Los siguientes parámetros son particularmente relevantes para las claves AES, pero no son necesarios para generar una:
Tag::BLOCK_MODE
especifica los modos de bloqueo con los que se puede usar la clave nueva.Tag::PADDING
especifica los modos de padding que se pueden usar. Esto solo es relevante para los modos ECB y CBC.
Si se especifica el modo de bloqueo de GCM, proporciona Tag::MIN_MAC_LENGTH.
Si se omite, el método muestra ErrorCode::MISSING_MIN_MAC_LENGTH
.
El valor de la etiqueta es un múltiplo de 8 y está entre 96 y 128.
Claves HMAC
Se requieren los siguientes parámetros para la generación de claves HMAC:
- Tag::KEY_SIZE especifica el tamaño de la clave en bits. No se admiten valores menores que 64 ni valores que no sean múltiplos de 8. Se admiten todos los múltiplos de 8, de 64 a 512. Es posible que se admitan valores más grandes.
- Tag::MIN_MAC_LENGTH especifica la longitud mínima de los MAC que se pueden generar o verificar con esta clave. El valor es un múltiplo de 8 y al menos 64.
- Tag::DIGEST especifica el algoritmo de resumen de la clave. Se especifica exactamente un resumen; de lo contrario, muestra
ErrorCode::UNSUPPORTED_DIGEST
. Si el trustlet no es compatible con el resumen, muestraErrorCode::UNSUPPORTED_DIGEST
.
Características clave
Si el argumento de características no es nulo, generateKey
muestra las características de la clave recién generada divididas de forma adecuada en listas de aplicación de hardware y software. Consulta getKeyCharacteristics para obtener una descripción de qué características van en qué lista. Las características que se muestran incluyen todos los parámetros especificados para la generación de claves, excepto Tag::APPLICATION_ID y Tag::APPLICATION_DATA.
Si estas etiquetas se incluyeron en los parámetros clave, se quitan de las características mostradas para que no sea posible encontrar sus valores examinando el BLOB de clave que se muestra. Sin embargo, están vinculados de manera criptográfica al BLOB de claves, por lo que, si no se proporcionan los valores correctos cuando se usa la clave, el uso falla. Del mismo modo, Tag::ROOT_OF_TRUST está vinculado criptográficamente a la clave, pero no se puede especificar durante la creación o importación de claves y nunca se muestra.
Además de las etiquetas proporcionadas, el trustlet también agrega Tag::ORIGIN, con el valor KeyOrigin::GENERATED
, y si la clave es resistente a la reversión,
Resistencia a la reversión
La resistencia a la reversión significa que, una vez que se borra una clave con deleteKey o deleteAllKeys, el hardware seguro garantiza que nunca se pueda volver a usar. Por lo general, las implementaciones sin resistencia a la reversión muestran al emisor el material de claves importado o generado como un BLOB de clave, un formulario encriptado y autenticado. Cuando el almacén de claves borra el BLOB de clave, esta desaparece, pero un atacante que anteriormente haya logrado recuperar el material de clave puede restablecerla en el dispositivo.
Una clave es resistente a la reversión si el hardware seguro garantiza que las claves borradas no se puedan restablecer más adelante. Por lo general, esto se hace almacenando metadatos de claves adicionales en una ubicación de confianza que un atacante no pueda manipular. Por lo general, en los dispositivos móviles, el mecanismo utilizado para esto es la repetición de bloques de memoria protegidos (RPMB). Debido a que la cantidad de claves que se pueden crear es, en esencia, ilimitada y el almacenamiento de confianza que se usa para la resistencia a la reversión puede ser limitado en tamaño, este método debe tener éxito incluso si no se puede proporcionar resistencia a la reversión para la clave nueva. En ese caso, no se debe agregar Tag::ROLLBACK_RESISTANT a las características clave.
getKeyCharacteristics
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como get_key_characteristics
y se le cambió el nombre en Keymaster 3.
Muestra los parámetros y las autorizaciones asociados con la clave proporcionada, divididos en dos conjuntos: aplicación forzosa de hardware y aplicación forzosa de software. La descripción que aparece aquí se aplica de la misma manera a las listas de características clave que muestran importKey y generateKey.
Si se proporcionó Tag::APPLICATION_ID
durante la generación o la importación de la clave, se proporciona el mismo valor a este método en el argumento clientId
. De lo contrario, el método muestra ErrorCode::INVALID_KEY_BLOB
. Del mismo modo, si se proporcionó Tag::APPLICATION_DATA
durante la generación o la importación, se proporciona el mismo valor a este método en el argumento appData
.
Las características que muestra este método describen por completo el tipo y el uso de la clave especificada.
La regla general para decidir si una etiqueta determinada pertenece a la lista aplicada por hardware o por software es que, si el hardware seguro garantiza por completo su significado, el hardware se aplica de manera forzosa. De lo contrario, se aplica mediante software. A continuación, se incluye una lista de etiquetas específicas cuya asignación correcta podría no ser clara:
- Tag::ALGORITHM, Tag::KEY_SIZE y Tag::RSA_PUBLIC_EXPONENT son propiedades intrínsecas de la clave. Para cualquier clave protegida por hardware, estas etiquetas se encuentran en la lista de hardware obligatorio.
- Los valores de Tag::DIGEST que admite el hardware seguro se colocan en la lista de hardware compatible. Los resúmenes no compatibles se incluyen en la lista de software compatible.
- Los valores de Tag::PADDING suelen ir en la lista de hardware compatible, a menos que exista la posibilidad de que el software deba realizar un modo de padding específico. En ese caso, se incluyen en la lista de aplicaciones que se aplican con software. Esta posibilidad surge para las claves RSA que permiten el relleno PSS o OAEP con algoritmos de resumen que no son compatibles con el hardware seguro.
- Tag::USER_SECURE_ID y Tag::USER_AUTH_TYPE se aplican de forma forzosa en el hardware solo si la autenticación del usuario se aplica de forma forzosa en el hardware. Para lograr esto, el trustlet de Keymaster y el trustlet de autenticación relevante deben ser seguros y compartir una clave HMAC secreta que se use para firmar y validar los tokens de autenticación. Consulta la página Autenticación para obtener más detalles.
- Las etiquetas Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME y Tag::USAGE_EXPIRE_DATETIME requieren acceso a un reloj de pared verificable y correcto. El hardware más seguro solo tiene acceso a la información de tiempo que proporciona el SO no seguro, lo que significa que las etiquetas se aplican mediante software.
- Tag::ORIGIN siempre está en la lista de hardware para claves vinculadas al hardware. Su presencia en esa lista es la forma en que las capas superiores determinan que una clave tiene una copia de seguridad en el hardware.
importKey
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como import_key
y se le cambió el nombre en Keymaster 3.
Importa material de claves al hardware de Keymaster. Los parámetros de definición de claves y las características de salida se manejan de la misma manera que para generateKey
, con las siguientes excepciones:
- Tag::KEY_SIZE y
Tag::RSA_PUBLIC_EXPONENT
(solo para claves RSA) no son necesarios en los parámetros de entrada. Si no se proporciona, el trustlet deduce los valores del material de clave proporcionado y agrega etiquetas y valores adecuados a las características clave. Si se proporcionan los parámetros, el trustlet los valida en función del material de claves. En el caso de una discrepancia, el método muestra
ErrorCode::IMPORT_PARAMETER_MISMATCH
. - La Tag::ORIGIN que se muestra tiene el mismo valor que
KeyOrigin::IMPORTED
.
exportKey
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como export_key
y se le cambió el nombre en Keymaster 3.
Exporta una clave pública de un par de claves RSA o EC de Keymaster.
Si se proporcionó Tag::APPLICATION_ID
durante la generación o la importación de claves, se proporciona el mismo valor a este método en el argumento clientId
. De lo contrario, el método muestra ErrorCode::INVALID_KEY_BLOB
. Del mismo modo, si se proporcionó Tag::APPLICATION_DATA
durante la generación o la importación, se proporciona el mismo valor a este método en el argumento appData
.
deleteKey
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como delete_key
y se le cambió el nombre en Keymaster 3.
Borra la clave proporcionada. Este método es opcional y solo lo implementan los módulos de Keymaster que proporcionan resistencia a la reversión.
deleteAllKeys
Versión: 1, 2, 3
Esta función se introdujo en Keymaster 1 como delete_all_keys
y se le cambió el nombre en Keymaster 3.
Borra todas las claves. Este método es opcional y solo lo implementan los módulos de Keymaster que proporcionan resistencia a la reversión.
destroyAttestationIds
Versión: 3
El método destroyAttestationIds()
se usa para inhabilitar de forma permanente la nueva función (opcional, pero muy recomendada) de certificación de ID. Si el TEE no tiene forma de garantizar que la certificación de ID se inhabilite de forma permanente después de llamar a este método, no se debe implementar la certificación de ID en absoluto. En ese caso, este método no hace nada y muestra ErrorCode::UNIMPLEMENTED
. Si se admite la certificación de ID, se debe implementar este método y se deben inhabilitar de forma permanente todos los intentos futuros de certificación de ID. Se puede llamar
al método cualquier cantidad de veces. Si la certificación de ID ya está inhabilitada de forma permanente, el método no hace nada y muestra ErrorCode::OK
.
Los únicos códigos de error que puede mostrar este método son ErrorCode::UNIMPLEMENTED
(si no se admite la certificación de ID), ErrorCode:OK
, ErrorCode::KEYMASTER_NOT_CONFIGURED
o uno de los códigos de error que indican que no se pudo establecer comunicación con el hardware seguro.
begin
Versión: 1, 2, 3
Inicia una operación criptográfica con la clave especificada, para el propósito especificado, con los parámetros especificados (según corresponda) y muestra un identificador de operación que se usa con update y finish para completar la operación. El identificador de operación también se usa como el token de "desafío" en las operaciones autenticadas y, para esas operaciones, se incluye en el campo challenge
del token de autenticación.
Una implementación de Keymaster admite al menos 16 operaciones simultáneas. El almacén de claves usa hasta 15, lo que deja uno para que vold use en la encriptación de contraseñas. Cuando Keystore tiene 15 operaciones en curso (se llamó a begin
, pero no a finish
ni a abort
) y recibe una solicitud para comenzar una 16ª, llama a abort
en la operación que se usó menos recientemente para reducir la cantidad de operaciones activas a 14 antes de llamar a begin
para iniciar la operación solicitada recientemente.
Si se especificaron Tag::APPLICATION_ID o Tag::APPLICATION_DATA durante la generación o importación de claves, las llamadas a begin
incluyen esas etiquetas con los valores especificados originalmente en el argumento inParams
de este método.
Aplicación de la autorización
Durante este método, el trustlet aplica las siguientes autorizaciones de claves si la implementación las colocó en las características "aplicadas por hardware" y si la operación no es una operación de clave pública. Las operaciones de clave pública, es decir, KeyPurpose::ENCRYPT
y KeyPurpose::VERIFY
, con claves RSA o EC, pueden tener éxito incluso si no se cumplen los requisitos de autorización.
- Tag::PURPOSE: El propósito especificado en la llamada a
begin()
debe coincidir con uno de los propósitos de las autorizaciones de claves, a menos que la operación solicitada sea una operación de clave pública. Si el propósito especificado no coincide y la operación no es una operación de clave pública,begin
muestraErrorCode::UNSUPPORTED_PURPOSE
. Las operaciones de clave pública son operaciones de encriptación o verificación asimétricas. - Tag::ACTIVE_DATETIME solo se puede aplicar si hay una fuente de hora UTC de confianza disponible. Si la fecha y hora actuales son anteriores al valor de la etiqueta, el método muestra
ErrorCode::KEY_NOT_YET_VALID
. - Tag::ORIGINATION_EXPIRE_DATETIME
solo se puede aplicar si hay una fuente de hora UTC de confianza disponible. Si la fecha y hora actuales son posteriores al valor de la etiqueta y el propósito es
KeyPurpose::ENCRYPT
oKeyPurpose::SIGN
, el método muestraErrorCode::KEY_EXPIRED
. - Tag::USAGE_EXPIRE_DATETIME solo se puede aplicar si hay una fuente de hora UTC de confianza disponible. Si la fecha y hora actuales son posteriores al valor de la etiqueta y el propósito es
KeyPurpose::DECRYPT
oKeyPurpose::VERIFY
, el método muestraErrorCode::KEY_EXPIRED
. - Tag::MIN_SECONDS_BETWEEN_OPS se compara con un temporizador relativo de confianza que indica el último uso de la clave. Si la última hora de uso más el valor de la etiqueta es menor que la hora actual, el método muestra
ErrorCode::KEY_RATE_LIMIT_EXCEEDED
. Consulta la descripción de la etiqueta para obtener detalles importantes sobre la implementación. - Tag::MAX_USES_PER_BOOT se compara con un contador seguro que realiza un seguimiento de los usos de la clave desde el inicio. Si el recuento de usos anteriores excede el valor de la etiqueta, el método muestra
ErrorCode::KEY_MAX_OPS_EXCEEDED
. - Este método aplica Tag::USER_SECURE_ID solo si la clave también tiene Tag::AUTH_TIMEOUT.
Si la clave tiene ambos, este método debe recibir un Tag::AUTH_TOKEN válido en
inParams
. Para que el token de autenticación sea válido, se deben cumplir todos los siguientes requisitos:- El campo HMAC se valida correctamente.
- Al menos uno de los valores de Tag::USER_SECURE_ID de la clave coincide con al menos uno de los valores de ID seguro en el token.
- La clave tiene una Tag::USER_AUTH_TYPE que coincide con el tipo de autorización en el token.
Si no se cumple alguna de estas condiciones, el método muestra
ErrorCode::KEY_USER_NOT_AUTHENTICATED
. - Tag::CALLER_NONCE permite que el llamador especifique un nonce o un vector de inicialización (IV). Si la clave no tiene esta etiqueta, pero el llamador proporcionó Tag::NONCE a este método, se muestra
ErrorCode::CALLER_NONCE_PROHIBITED
. - Tag::BOOTLOADER_ONLY especifica que solo el bootloader puede usar la clave. Si se llama a este método con una clave solo para el bootloader después de que este termine de ejecutarse, muestra
ErrorCode::INVALID_KEY_BLOB
.
Claves RSA
Todas las operaciones de claves RSA especifican exactamente un modo de padding en inParams
.
Si no se especifica o se especifica más de una vez, el método muestra ErrorCode::UNSUPPORTED_PADDING_MODE
.
Las operaciones de firma y verificación de RSA necesitan un resumen, al igual que las operaciones de encriptación y desencriptación de RSA con el modo de relleno OAEP. En esos casos, el llamador especifica exactamente un resumen en inParams
. Si no se especifica o se especifica más de una vez, el método muestra ErrorCode::UNSUPPORTED_DIGEST
.
Las operaciones de clave privada (KeyPurpose::DECYPT
y KeyPurpose::SIGN
) necesitan autorización de resumen y padding, lo que significa que las autorizaciones de clave deben contener los valores especificados. De lo contrario, el método muestra ErrorCode::INCOMPATIBLE_DIGEST
o ErrorCode::INCOMPATIBLE_PADDING
, según corresponda. Las operaciones de clave pública (KeyPurpose::ENCRYPT
y KeyPurpose::VERIFY
) se permiten con un resumen o relleno no autorizado.
Con la excepción de PaddingMode::NONE
, todos los modos de padding de RSA solo se aplican a ciertos fines. Específicamente, PaddingMode::RSA_PKCS1_1_5_SIGN
y PaddingMode::RSA_PSS
solo admiten la firma y la verificación, mientras que PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
y PaddingMode::RSA_OAEP
solo admiten la encriptación y la desencriptación.
El método muestra ErrorCode::UNSUPPORTED_PADDING_MODE
si el modo especificado no admite el propósito especificado.
Existen algunas interacciones importantes entre los modos de padding y los resúmenes:
PaddingMode::NONE
indica que se realiza una operación de RSA "sin procesar". Si se firma o se verifica, se especificaDigest::NONE
para el resumen. No se necesita un resumen para la encriptación o desencriptación sin padding.- El padding de
PaddingMode::RSA_PKCS1_1_5_SIGN
requiere un resumen. El resumen puede serDigest::NONE
, en cuyo caso la implementación de Keymaster no puede compilar una estructura de firma PKCS#1 v1.5 adecuada, ya que no puede agregar la estructura de DigestInfo. En su lugar, la implementación construye0x00 || 0x01 || PS || 0x00 || M
, donde M es el mensaje proporcionado y PS es la cadena de padding. El tamaño de la clave RSA debe ser de al menos 11 bytes más grande que el mensaje; de lo contrario, el método muestraErrorCode::INVALID_INPUT_LENGTH
. - El padding
PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
no requiere un resumen. - El padding
PaddingMode::RSA_PSS
requiere un resumen, que no puede serDigest::NONE
. Si se especificaDigest::NONE
, el método muestraErrorCode::INCOMPATIBLE_DIGEST
. Además, el tamaño de la clave RSA debe ser de al menos 2 + D bytes más grande que el tamaño de salida del resumen, donde D es el tamaño del resumen, en bytes. De lo contrario, el método muestraErrorCode::INCOMPATIBLE_DIGEST
. El tamaño de la sal es D. - El padding
PaddingMode::RSA_OAEP
requiere un resumen, que no puede serDigest::NONE
. Si se especificaDigest::NONE
, el método muestraErrorCode::INCOMPATIBLE_DIGEST
.
Claves de EC
Las operaciones de claves de EC especifican exactamente un modo de padding en inParams
.
Si no se especifica o se especifica más de una vez, el método muestra ErrorCode::UNSUPPORTED_PADDING_MODE
.
Las operaciones de claves privadas (KeyPurpose::SIGN
) necesitan autorización de resumen y padding, lo que significa que las autorizaciones de claves deben contener los valores especificados. De lo contrario, muestra ErrorCode::INCOMPATIBLE_DIGEST
. Las operaciones de clave pública (KeyPurpose::VERIFY
) se permiten con un resumen o relleno no autorizado.
Claves AES
Las operaciones de claves AES especifican exactamente un modo de bloque y un modo de relleno en inParams
. Si no se especifica ninguno de los valores o se especifica más de una vez, muestra ErrorCode::UNSUPPORTED_BLOCK_MODE
o ErrorCode::UNSUPPORTED_PADDING_MODE
. La clave debe autorizar los modos especificados; de lo contrario, el método muestra ErrorCode::INCOMPATIBLE_BLOCK_MODE
o ErrorCode::INCOMPATIBLE_PADDING_MODE
.
Si el modo de bloqueo es BlockMode::GCM
, inParams
especifica Tag::MAC_LENGTH
y el
valor especificado es un múltiplo de 8 que no es mayor que 128
ni menor que el valor de Tag::MIN_MAC_LENGTH
en las
autorizaciones de claves. Para longitudes de MAC superiores a 128 o que no sean múltiplos de 8, muestra ErrorCode::UNSUPPORTED_MAC_LENGTH
. Para valores menores que la longitud mínima de la clave, muestra ErrorCode::INVALID_MAC_LENGTH
.
Si el modo de bloque es BlockMode::GCM
o BlockMode::CTR
, el modo de padding especificado debe ser PaddingMode::NONE
.
Para BlockMode::ECB
o BlockMode::CBC
, el modo puede ser PaddingMode::NONE
o PaddingMode::PKCS7
. Si el modo de padding no cumple con estas condiciones, muestra ErrorCode::INCOMPATIBLE_PADDING_MODE
.
Si el modo de bloqueo es BlockMode::CBC
, BlockMode::CTR
o BlockMode::GCM
, se necesita un vector de inicialización o un nonce.
En la mayoría de los casos, los emisores no deben proporcionar un IV o un nonce. En ese caso, la implementación de Keymaster genera un IV o nonce aleatorio y lo muestra con Tag::NONCE en outParams
.
Los IV de CBC y CTR son de 16 bytes. Los nonces de GCM son de 12 bytes. Si las autorizaciones clave contienen Tag::CALLER_NONCE, el llamador puede proporcionar un IV o nonce con Tag::NONCE en inParams
. Si se proporciona un nonce cuando Tag::CALLER_NONCE no está autorizado, muestra ErrorCode::CALLER_NONCE_PROHIBITED
.
Si no se proporciona un nonce cuando se autoriza Tag::CALLER_NONCE, genera un IV/nonce aleatorio.
Claves HMAC
Las operaciones de claves HMAC especifican Tag::MAC_LENGTH
en inParams
.
El valor especificado debe ser un múltiplo de 8 que no sea mayor que la longitud del resumen ni que el valor de Tag::MIN_MAC_LENGTH
en las autorizaciones de clave. Para longitudes de MAC mayores que la longitud del resumen o que no sean múltiplos de 8, muestra ErrorCode::UNSUPPORTED_MAC_LENGTH
.
Para valores menores que la longitud mínima de la clave, muestra ErrorCode::INVALID_MAC_LENGTH
.
update
Versión: 1, 2, 3
Proporciona datos para procesar en una operación en curso iniciada con begin.
El parámetro operationHandle
especifica la operación.
Para proporcionar más flexibilidad en el manejo de búferes, las implementaciones de este método tienen la opción de consumir menos datos de los proporcionados. El llamador es responsable de realizar un bucle para enviar el resto de los datos en llamadas posteriores. La cantidad de entrada consumida se muestra en el parámetro inputConsumed
.
Las implementaciones siempre consumen al menos un byte, a menos que la operación no pueda aceptar más. Si se proporcionan más de cero bytes y se consumen cero bytes, los llamadores consideran que esto es un error y abortan la operación.
Las implementaciones también pueden elegir cuántos datos mostrar como resultado de la actualización. Esto solo es relevante para las operaciones de encriptación y desencriptación, ya que la firma y la verificación no muestran datos hasta que se finaliza. Muestra los datos lo antes posible, en lugar de almacenarlos en búfer.
Manejo de errores
Si este método muestra un código de error distinto de ErrorCode::OK
, se anula la operación y se invalida el controlador de operación. Cualquier uso futuro del controlador con este método, finish o abort, mostrará ErrorCode::INVALID_OPERATION_HANDLE
.
Aplicación forzosa de la autorización
La aplicación forzosa de la autorización de claves se realiza principalmente en begin. La única excepción es el caso en el que la clave tiene lo siguiente:
- Uno o más Tag::USER_SECURE_IDs
- No tiene un Tag::AUTH_TIMEOUT.
En este caso, la clave requiere una autorización por operación, y el método de actualización recibe un Tag::AUTH_TOKEN en el argumento inParams
. HMAC verifica que el token sea válido y contenga un ID de usuario seguro que coincida, con la Tag::USER_AUTH_TYPE de la clave y que contenga el controlador de operación de la operación actual en el campo de desafío. Si no se cumplen estas condiciones, muestra ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
El llamador proporciona el token de autenticación a cada llamada para actualizar y finalizar. La implementación solo necesita validar el token una vez, si así lo prefiere.
Claves RSA
Para las operaciones de firma y verificación con Digest::NONE
, este método acepta que se firme o verifique todo el bloque en una sola actualización. No puede consumir solo una parte del bloque. Sin embargo, si el llamador elige proporcionar los datos en varias actualizaciones, este método los acepta.
Si el llamador proporciona más datos para firmar de los que se pueden usar (la longitud de los datos supera el tamaño de la clave RSA), muestra ErrorCode::INVALID_INPUT_LENGTH
.
Claves ECDSA
Para las operaciones de firma y verificación con Digest::NONE
, este método acepta que todo el bloque se firme o verifique en una sola actualización. Este método no puede consumir solo una parte del bloque.
Sin embargo, si el llamador elige proporcionar los datos en varias actualizaciones, este método los acepta. Si el emisor proporciona más datos para firmar de los que pueden usarse, los datos se truncan de manera silenciosa. (Esto difiere del manejo de datos excesivos proporcionados en operaciones de RSA similares. El motivo de esto es la compatibilidad con clientes heredados).
Claves AES
El modo AES GCM admite "datos de autenticación asociados", que se proporcionan a través de la etiqueta Tag::ASSOCIATED_DATA en el argumento inParams
.
Los datos asociados se pueden proporcionar en llamadas repetidas (importante si los datos son demasiado grandes para enviarlos en un solo bloque), pero siempre preceden a los datos que se encriptarán o desencriptarán. Una llamada de actualización puede recibir datos asociados y datos para encriptar o desencriptar, pero las actualizaciones posteriores no pueden incluir datos asociados. Si el llamador proporciona datos asociados a una llamada de actualización después de una llamada que incluye datos para encriptar o desencriptar, muestra ErrorCode::INVALID_TAG
.
Para la encriptación de GCM, la etiqueta se agrega al texto cifrado por finish. Durante la desencriptación, los últimos Tag::MAC_LENGTH
bytes de los datos proporcionados a la última llamada de actualización son la etiqueta. Debido a que una invocación determinada de update no puede saber si es la última invocación, procesa todas las funciones, excepto la longitud de la etiqueta, y almacena en búfer los datos de etiqueta posibles durante finish.
finalizar
Versión: 1, 2, 3
Finaliza una operación en curso iniciada con begin y procesa todos los datos aún sin procesar que proporcionan las actualizaciones.
Este método es el último al que se llama en una operación, por lo que se muestran todos los datos procesados.
Si se completa correctamente o muestra un error, este método finaliza la operación y, por lo tanto, invalida el controlador de operación proporcionado. Cualquier uso futuro del identificador, con este método o update o abort, muestra ErrorCode::INVALID_OPERATION_HANDLE
.
Las operaciones de firma muestran la firma como resultado. Las operaciones de verificación aceptan la firma en el parámetro signature
y no muestran ningún resultado.
Aplicación forzosa de la autorización
La aplicación forzosa de la autorización de claves se realiza principalmente en begin. La única excepción es el caso en el que la clave tiene lo siguiente:
- Uno o más Tag::USER_SECURE_IDs
- No tiene una Tag::AUTH_TIMEOUT.
En este caso, la clave requiere una autorización por operación, y el método de actualización recibe un Tag::AUTH_TOKEN en el argumento inParams
. El HMAC verifica que el token sea válido y contenga un ID de usuario seguro que coincida, que coincida con el Tag::USER_AUTH_TYPE de la clave y que contenga el identificador de operación de la operación actual en el campo de desafío. Si no se cumplen estas condiciones, muestra ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
El llamador proporciona el token de autenticación a cada llamada para actualizar y finalizar. La implementación solo debe validar el token una vez si lo prefiere.
Claves RSA
Algunos requisitos adicionales, según el modo de padding:
PaddingMode::NONE
. Para las operaciones de firma y encriptación sin padding, si los datos proporcionados son más cortos que la clave, se agregará padding de cero a la izquierda antes de la firma o la encriptación. Si los datos tienen la misma longitud que la clave, pero son numéricamente más grandes, muestraErrorCode::INVALID_ARGUMENT
. Para las operaciones de verificación y desencriptación, los datos deben tener exactamente la misma longitud que la clave. De lo contrario, muestraErrorCode::INVALID_INPUT_LENGTH.
.PaddingMode::RSA_PSS
. Para las operaciones de firma con relleno de PSS, la sal de PSS es el tamaño del resumen del mensaje y se genera de forma aleatoria. El resumen especificado con Tag::DIGEST eninputParams
en begin se usa como el algoritmo de resumen de PSS y como el algoritmo de resumen de MGF1.PaddingMode::RSA_OAEP
. El resumen especificado con Tag::DIGEST eninputParams
en begin se usa como el algoritmo de resumen OAEP, y SHA1 se usa como el algoritmo de resumen MGF1.
Claves ECDSA
Si los datos proporcionados para la firma o verificación sin padding son demasiado largos, recórtalos.
Claves AES
Estas son algunas condiciones adicionales, según el modo de bloqueo:
BlockMode::ECB
oBlockMode::CBC
. Si el padding esPaddingMode::NONE
y la longitud de los datos no es un múltiplo del tamaño del bloque de AES, muestraErrorCode::INVALID_INPUT_LENGTH
. Si el relleno esPaddingMode::PKCS7
, rellena los datos según la especificación PKCS#7. Ten en cuenta que PKCS#7 recomienda agregar un bloque de relleno adicional si los datos son un múltiplo de la longitud del bloque.BlockMode::GCM
. Durante el encriptado, después de procesar todo el texto simple, calcula la etiqueta (Tag::MAC_LENGTH bytes) y adjúntalo al texto cifrado que se muestra. Durante la desencriptación, procesa los últimos Tag::MAC_LENGTH bytes como la etiqueta. Si la verificación de la etiqueta falla, muestraErrorCode::VERIFICATION_FAILED
.
anular
Versión: 1, 2, 3
Anula la operación en curso. Después de la llamada para abortar, muestra ErrorCode::INVALID_OPERATION_HANDLE
para cualquier uso posterior del identificador de operación proporcionado con update, finish o abort.
get_supported_algorithms
Versión: 1
Muestra la lista de algoritmos compatibles con la implementación de hardware de Keymaster. Una implementación de software muestra una lista vacía; una implementación híbrida muestra una lista que contiene solo los algoritmos que admite el hardware.
Las implementaciones de Keymaster 1 admiten RSA, EC, AES y HMAC.
get_supported_block_modes
Versión: 1
Muestra la lista de modos de bloqueo AES compatibles con la implementación de hardware de Keymaster para un algoritmo y un propósito especificados.
Para RSA, EC y HMAC, que no son algoritmos de cifrado por bloques, el método muestra una lista vacía para todos los fines válidos. Los fines no válidos deberían hacer que el método muestre ErrorCode::INVALID_PURPOSE
.
Las implementaciones de Keymaster 1 admiten ECB, CBC, CTR y GCM para la encriptación y desencriptación AES.
get_supported_padding_modes
Versión: 1
Muestra la lista de modos de relleno compatibles con la implementación de hardware de Keymaster para un algoritmo y un propósito especificados.
HMAC y EC no tienen noción de padding, por lo que el método muestra una lista vacía para todos los fines válidos. Los fines no válidos deben hacer que el método muestre ErrorCode::INVALID_PURPOSE
.
En el caso de RSA, las implementaciones de Keymaster 1 admiten lo siguiente:
- Encriptación, desencriptación, firma y verificación sin rellenar. Para la encriptación y firma sin padding, si el mensaje es más corto que el módulo público, las implementaciones deben rellenarlo con ceros a la izquierda. Para la desencriptación y verificación sin rellenar, la longitud de entrada debe coincidir con el tamaño del módulo público.
- Modos de relleno de encriptación y firma PKCS#1 v1.5
- PSS con una longitud mínima de sal de 20
- OAEP
Para AES en los modos ECB y CBC, las implementaciones de Keymaster 1 no admiten padding ni padding PKCS#7. Los modos CTR y GCM solo admiten no relleno.
get_supported_digests
Versión: 1
Muestra la lista de modos de resumen compatibles con la implementación de hardware de Keymaster para un algoritmo y un propósito especificados.
Ninguno de los modos de AES admite ni requiere el resumen, por lo que el método muestra una lista vacía para fines válidos.
Las implementaciones de Keymaster 1 pueden implementar un subconjunto de los resúmenes definidos. Las implementaciones proporcionan SHA-256 y pueden proporcionar MD5, SHA1, SHA-224, SHA-256, SHA384 y SHA512 (el conjunto completo de resúmenes definidos).
get_supported_import_formats
Versión: 1
Muestra la lista de formatos de importación compatibles con la implementación de hardware de Keymaster de un algoritmo especificado.
Las implementaciones de Keymaster 1 admiten el formato PKCS#8 (sin protección con contraseña) para importar pares de claves RSA y EC, y admiten la importación sin procesar de material de claves AES y HMAC.
get_supported_export_formats
Versión: 1
Muestra la lista de formatos de exportación compatibles con la implementación de hardware de Keymaster de un algoritmo especificado.
Las implementaciones de Keymaster1 admiten el formato X.509 para exportar claves públicas RSA y EC. No se admite la exportación de claves privadas ni claves asimétricas.
Funciones históricas
Keymaster 0
Las siguientes funciones pertenecen a la definición original de Keymaster 0. Estaban presentes en la estructura keymaster1_device_t de Keymaster 1. Sin embargo, en Keymaster 1.0, no se implementaron, y sus punteros de función se establecieron en NULL.
generate_keypair
import_keypair
get_keypair_public
delete_keypair
delete_all
sign_data
Verify_data
Keymaster 1
Las siguientes funciones pertenecen a la definición de Keymaster 1, pero se quitaron en Keymaster 2, junto con las funciones de Keymaster 0 que se mencionaron anteriormente.
get_supported_algorithms
get_supported_block_modes
get_supported_padding_modes
get_supported_digests
get_supported_import_formats
get_supported_export_formats
Keymaster 2
Las siguientes funciones pertenecen a la definición de Keymaster 2, pero se quitaron en Keymaster 3, junto con las funciones de Keymaster 1 que se enumeraron anteriormente.
configure