X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fcrypto_backend%2Fcrypto_nss.c;h=c15481270fb8d22aa847da4d144b29428da99432;hb=420ad62f0bb77970a6ba234bde9e1405f7df7789;hp=0911245b47d9b935a615a38d6fefa2967f0b32bf;hpb=83f02e66827fa6fa66f9b73a009d2ba51d22352d;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c index 0911245..c154812 100644 --- a/lib/crypto_backend/crypto_nss.c +++ b/lib/crypto_backend/crypto_nss.c @@ -1,20 +1,21 @@ /* * NSS crypto backend implementation * - * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2012, Milan Broz + * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2023 Milan Broz * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -22,7 +23,7 @@ #include #include #include -#include "crypto_backend.h" +#include "crypto_backend_internal.h" #define CONST_CAST(x) (x)(uintptr_t) @@ -34,14 +35,15 @@ struct hash_alg { SECOidTag oid; CK_MECHANISM_TYPE ck_type; int length; + unsigned int block_length; }; static struct hash_alg hash_algs[] = { - { "sha1", SEC_OID_SHA1, CKM_SHA_1_HMAC, 20 }, - { "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32 }, - { "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48 }, - { "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64 }, -// { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20 }, + { "sha1", SEC_OID_SHA1, CKM_SHA_1_HMAC, 20, 64 }, + { "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32, 64 }, + { "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48, 128 }, + { "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64, 128 }, +// { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20, 64 }, { NULL, 0, 0, 0 } }; @@ -57,6 +59,10 @@ struct crypt_hmac { const struct hash_alg *hash; }; +struct crypt_cipher { + struct crypt_cipher_kernel ck; +}; + static struct hash_alg *_get_alg(const char *name) { int i = 0; @@ -69,8 +75,10 @@ static struct hash_alg *_get_alg(const char *name) return NULL; } -int crypt_backend_init(struct crypt_device *ctx) +int crypt_backend_init(bool fips __attribute__((unused))) { + int r; + if (crypto_backend_initialised) return 0; @@ -78,14 +86,22 @@ int crypt_backend_init(struct crypt_device *ctx) return -EINVAL; #if HAVE_DECL_NSS_GETVERSION - snprintf(version, 64, "NSS %s", NSS_GetVersion()); + r = snprintf(version, sizeof(version), "NSS %s", NSS_GetVersion()); #else - snprintf(version, 64, "NSS"); + r = snprintf(version, sizeof(version), "NSS"); #endif + if (r < 0 || (size_t)r >= sizeof(version)) + return -EINVAL; + crypto_backend_initialised = 1; return 0; } +void crypt_backend_destroy(void) +{ + crypto_backend_initialised = 0; +} + uint32_t crypt_backend_flags(void) { return 0; @@ -162,7 +178,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) return -EINVAL; memcpy(buffer, tmp, length); - memset(tmp, 0, sizeof(tmp)); + crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) return -EINVAL; @@ -173,12 +189,11 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) return 0; } -int crypt_hash_destroy(struct crypt_hash *ctx) +void crypt_hash_destroy(struct crypt_hash *ctx) { PK11_DestroyContext(ctx->md, PR_TRUE); memset(ctx, 0, sizeof(*ctx)); free(ctx); - return 0; } /* HMAC */ @@ -188,15 +203,15 @@ int crypt_hmac_size(const char *name) } int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, - const void *buffer, size_t length) + const void *key, size_t key_length) { struct crypt_hmac *h; SECItem keyItem; SECItem noParams; keyItem.type = siBuffer; - keyItem.data = CONST_CAST(unsigned char *)buffer; - keyItem.len = (int)length; + keyItem.data = CONST_CAST(unsigned char *)key; + keyItem.len = (int)key_length; noParams.type = siBuffer; noParams.data = 0; @@ -210,28 +225,28 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, h->hash = _get_alg(name); if (!h->hash) - goto bad; + goto err; h->slot = PK11_GetInternalKeySlot(); if (!h->slot) - goto bad; + goto err; h->key = PK11_ImportSymKey(h->slot, h->hash->ck_type, PK11_OriginUnwrap, CKA_SIGN, &keyItem, NULL); if (!h->key) - goto bad; + goto err; h->md = PK11_CreateContextBySymKey(h->hash->ck_type, CKA_SIGN, h->key, &noParams); if (!h->md) - goto bad; + goto err; if (PK11_DigestBegin(h->md) != SECSuccess) - goto bad; + goto err; *ctx = h; return 0; -bad: +err: crypt_hmac_destroy(h); return -EINVAL; } @@ -264,7 +279,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) return -EINVAL; memcpy(buffer, tmp, length); - memset(tmp, 0, sizeof(tmp)); + crypt_backend_memzero(tmp, sizeof(tmp)); if (tmp_len < length) return -EINVAL; @@ -275,7 +290,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) return 0; } -int crypt_hmac_destroy(struct crypt_hmac *ctx) +void crypt_hmac_destroy(struct crypt_hmac *ctx) { if (ctx->key) PK11_FreeSymKey(ctx->key); @@ -285,11 +300,10 @@ int crypt_hmac_destroy(struct crypt_hmac *ctx) PK11_DestroyContext(ctx->md, PR_TRUE); memset(ctx, 0, sizeof(*ctx)); free(ctx); - return 0; } /* RNG */ -int crypt_backend_rng(char *buffer, size_t length, int quality, int fips) +int crypt_backend_rng(char *buffer, size_t length, int quality __attribute__((unused)), int fips) { if (fips) return -EINVAL; @@ -305,11 +319,89 @@ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, - unsigned int iterations) + uint32_t iterations, uint32_t memory, uint32_t parallel) { - if (!kdf || strncmp(kdf, "pbkdf2", 6)) + struct hash_alg *ha; + + if (!kdf) return -EINVAL; - return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, - iterations, key_length, key); + if (!strcmp(kdf, "pbkdf2")) { + ha = _get_alg(hash); + if (!ha) + return -EINVAL; + + return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, + iterations, key_length, key, ha->block_length); + } else if (!strncmp(kdf, "argon2", 6)) { + return argon2(kdf, password, password_length, salt, salt_length, + key, key_length, iterations, memory, parallel); + } + + return -EINVAL; +} + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + struct crypt_cipher *h; + int r; + + h = malloc(sizeof(*h)); + if (!h) + return -ENOMEM; + + r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length); + if (r < 0) { + free(h); + return r; + } + + *ctx = h; + return 0; +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(&ctx->ck); + free(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(&ctx->ck, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length); +} + +bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused))) +{ + return true; +} + +int crypt_bitlk_decrypt_key(const void *key, size_t key_length, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length, + const char *tag, size_t tag_length) +{ + return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length, + iv, iv_length, tag, tag_length); +} + +int crypt_backend_memeq(const void *m1, const void *m2, size_t n) +{ + return NSS_SecureMemcmp(m1, m2, n); +} + +bool crypt_fips_mode(void) +{ + return false; }