summaryrefslogtreecommitdiff
path: root/ta/pkcs11/src/persistent_token.c
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2020-04-09 12:30:03 +0200
committerJérôme Forissier <jerome@forissier.org>2020-04-16 15:42:19 +0200
commitbef8bc684207124e10d768c25fdf398db52610cf (patch)
treebb02c334597ad093839879f1e478bf7e7db6b712 /ta/pkcs11/src/persistent_token.c
parent8e03579eea6477af3dfb4597cb0d5983318a3a77 (diff)
ta: pkcs11: helpers for PIN hashing
Adds helpers to hash PIN and to verify the hash of a PIN. The PIN is hashed together with user type and a generated salt. A used salt never takes the value 0 so that can be used to tell if a PIN is set. Acked-by: Rouven Czerwinski <r.czerwinski@pengutronix.de> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'ta/pkcs11/src/persistent_token.c')
-rw-r--r--ta/pkcs11/src/persistent_token.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/ta/pkcs11/src/persistent_token.c b/ta/pkcs11/src/persistent_token.c
index b68c0399..29c701e7 100644
--- a/ta/pkcs11/src/persistent_token.c
+++ b/ta/pkcs11/src/persistent_token.c
@@ -73,6 +73,64 @@ static TEE_Result open_pin_file(struct ck_token *token,
0, out_hdl);
}
+static enum pkcs11_rc do_hash(uint32_t user, const uint8_t *pin,
+ size_t pin_size, uint32_t salt,
+ uint8_t hash[TEE_MAX_HASH_SIZE])
+{
+ TEE_Result res = TEE_SUCCESS;
+ TEE_OperationHandle oh = TEE_HANDLE_NULL;
+ uint32_t sz = TEE_MAX_HASH_SIZE;
+
+ res = TEE_AllocateOperation(&oh, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0);
+ if (res)
+ return tee2pkcs_error(res);
+
+ TEE_DigestUpdate(oh, &user, sizeof(user));
+ TEE_DigestUpdate(oh, &salt, sizeof(salt));
+ res = TEE_DigestDoFinal(oh, pin, pin_size, hash, &sz);
+ TEE_FreeOperation(oh);
+
+ if (res)
+ return PKCS11_CKR_GENERAL_ERROR;
+
+ memset(hash + sz, 0, TEE_MAX_HASH_SIZE - sz);
+ return PKCS11_CKR_OK;
+}
+
+enum pkcs11_rc hash_pin(enum pkcs11_user_type user, const uint8_t *pin,
+ size_t pin_size, uint32_t *salt,
+ uint8_t hash[TEE_MAX_HASH_SIZE])
+{
+ enum pkcs11_rc rc = PKCS11_CKR_OK;
+ uint32_t s = 0;
+
+ TEE_GenerateRandom(&s, sizeof(s));
+ if (!s)
+ s++;
+
+ rc = do_hash(user, pin, pin_size, s, hash);
+ if (!rc)
+ *salt = s;
+ return rc;
+}
+
+enum pkcs11_rc verify_pin(enum pkcs11_user_type user, const uint8_t *pin,
+ size_t pin_size, uint32_t salt,
+ const uint8_t hash[TEE_MAX_HASH_SIZE])
+{
+ uint8_t tmp_hash[TEE_MAX_HASH_SIZE] = { 0 };
+ enum pkcs11_rc rc = PKCS11_CKR_OK;
+
+ rc = do_hash(user, pin, pin_size, salt, tmp_hash);
+ if (rc)
+ return rc;
+
+ if (buf_compare_ct(tmp_hash, hash, TEE_MAX_HASH_SIZE))
+ rc = PKCS11_CKR_PIN_INCORRECT;
+
+ return rc;
+}
+
static void init_pin_keys(struct ck_token *token, enum pkcs11_user_type user)
{
TEE_Result res = TEE_ERROR_GENERIC;