X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fcrypto_backend%2Fcrypto_nettle.c;h=c2ec305dab8e605d9bb03859256c292537a6dd9b;hb=322b430a2589cdc7985e98a14ec12322b91c9d5e;hp=cc6617ae07571b695c61bcabd9753f12ebf6f15a;hpb=ad21d48762fa70838d4ab4fbe8fe2a2e8a4dcef1;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c index cc6617a..c2ec305 100644 --- a/lib/crypto_backend/crypto_nettle.c +++ b/lib/crypto_backend/crypto_nettle.c @@ -1,8 +1,8 @@ /* * Nettle crypto backend implementation * - * Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved. - * Copyright (C) 2011-2014, Milan Broz + * Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2020 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,16 +23,24 @@ #include #include #include +#include #include #include -#include "crypto_backend.h" +#include "crypto_backend_internal.h" -static char *version = "Nettle"; +#if HAVE_NETTLE_VERSION_H +#include +#define VSTR(s) STR(s) +#define STR(s) #s +static const char *version = "Nettle "VSTR(NETTLE_VERSION_MAJOR)"."VSTR(NETTLE_VERSION_MINOR); +#else +static const char *version = "Nettle"; +#endif typedef void (*init_func) (void *); -typedef void (*update_func) (void *, unsigned, const uint8_t *); -typedef void (*digest_func) (void *, unsigned, uint8_t *); -typedef void (*set_key_func) (void *, unsigned, const uint8_t *); +typedef void (*update_func) (void *, size_t, const uint8_t *); +typedef void (*digest_func) (void *, size_t, uint8_t *); +typedef void (*set_key_func) (void *, size_t, const uint8_t *); struct hash_alg { const char *name; @@ -45,6 +53,24 @@ struct hash_alg { set_key_func hmac_set_key; }; +/* Missing HMAC wrappers in Nettle */ +#define HMAC_FCE(xxx) \ +struct xhmac_##xxx##_ctx HMAC_CTX(struct xxx##_ctx); \ +static void xhmac_##xxx##_set_key(struct xhmac_##xxx##_ctx *ctx, \ +size_t key_length, const uint8_t *key) \ +{HMAC_SET_KEY(ctx, &nettle_##xxx, key_length, key);} \ +static void xhmac_##xxx##_update(struct xhmac_##xxx##_ctx *ctx, \ +size_t length, const uint8_t *data) \ +{xxx##_update(&ctx->state, length, data);} \ +static void xhmac_##xxx##_digest(struct xhmac_##xxx##_ctx *ctx, \ +size_t length, uint8_t *digest) \ +{HMAC_DIGEST(ctx, &nettle_##xxx, length, digest);} + +HMAC_FCE(sha3_224); +HMAC_FCE(sha3_256); +HMAC_FCE(sha3_384); +HMAC_FCE(sha3_512); + static struct hash_alg hash_algs[] = { { "sha1", SHA1_DIGEST_SIZE, (init_func) sha1_init, @@ -94,6 +120,41 @@ static struct hash_alg hash_algs[] = { (digest_func) hmac_ripemd160_digest, (set_key_func) hmac_ripemd160_set_key, }, +/* Nettle prior to version 3.2 has incompatible SHA3 implementation */ +#if NETTLE_SHA3_FIPS202 + { "sha3-224", SHA3_224_DIGEST_SIZE, + (init_func) sha3_224_init, + (update_func) sha3_224_update, + (digest_func) sha3_224_digest, + (update_func) xhmac_sha3_224_update, + (digest_func) xhmac_sha3_224_digest, + (set_key_func) xhmac_sha3_224_set_key, + }, + { "sha3-256", SHA3_256_DIGEST_SIZE, + (init_func) sha3_256_init, + (update_func) sha3_256_update, + (digest_func) sha3_256_digest, + (update_func) xhmac_sha3_256_update, + (digest_func) xhmac_sha3_256_digest, + (set_key_func) xhmac_sha3_256_set_key, + }, + { "sha3-384", SHA3_384_DIGEST_SIZE, + (init_func) sha3_384_init, + (update_func) sha3_384_update, + (digest_func) sha3_384_digest, + (update_func) xhmac_sha3_384_update, + (digest_func) xhmac_sha3_384_digest, + (set_key_func) xhmac_sha3_384_set_key, + }, + { "sha3-512", SHA3_512_DIGEST_SIZE, + (init_func) sha3_512_init, + (update_func) sha3_512_update, + (digest_func) sha3_512_digest, + (update_func) xhmac_sha3_512_update, + (digest_func) xhmac_sha3_512_digest, + (set_key_func) xhmac_sha3_512_set_key, + }, +#endif { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, } }; @@ -105,6 +166,11 @@ struct crypt_hash { struct sha256_ctx sha256; struct sha384_ctx sha384; struct sha512_ctx sha512; + struct ripemd160_ctx ripemd160; + struct sha3_224_ctx sha3_224; + struct sha3_256_ctx sha3_256; + struct sha3_384_ctx sha3_384; + struct sha3_512_ctx sha3_512; } nettle_ctx; }; @@ -116,11 +182,20 @@ struct crypt_hmac { struct hmac_sha256_ctx sha256; struct hmac_sha384_ctx sha384; struct hmac_sha512_ctx sha512; + struct hmac_ripemd160_ctx ripemd160; + struct xhmac_sha3_224_ctx sha3_224; + struct xhmac_sha3_256_ctx sha3_256; + struct xhmac_sha3_384_ctx sha3_384; + struct xhmac_sha3_512_ctx sha3_512; } nettle_ctx; size_t key_length; uint8_t *key; }; +struct crypt_cipher { + struct crypt_cipher_kernel ck; +}; + uint32_t crypt_backend_flags(void) { return 0; @@ -138,11 +213,16 @@ static struct hash_alg *_get_alg(const char *name) return NULL; } -int crypt_backend_init(struct crypt_device *ctx) +int crypt_backend_init(void) { return 0; } +void crypt_backend_destroy(void) +{ + return; +} + const char *crypt_backend_version(void) { return version; @@ -197,11 +277,10 @@ 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) { memset(ctx, 0, sizeof(*ctx)); free(ctx); - return 0; } /* HMAC */ @@ -211,7 +290,7 @@ 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; @@ -225,12 +304,12 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, if (!h->hash) goto bad; - h->key = malloc(length); + h->key = malloc(key_length); if (!h->key) goto bad; - memcpy(h->key, buffer, length); - h->key_length = length; + memcpy(h->key, key, key_length); + h->key_length = key_length; h->hash->init(&h->nettle_ctx); h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key); @@ -263,13 +342,12 @@ 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) { memset(ctx->key, 0, ctx->key_length); free(ctx->key); memset(ctx, 0, sizeof(*ctx)); free(ctx); - return 0; } /* RNG - N/A */ @@ -283,23 +361,84 @@ 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) { struct crypt_hmac *h; int r; - if (!kdf || strncmp(kdf, "pbkdf2", 6)) + if (!kdf) return -EINVAL; - r = crypt_hmac_init(&h, hash, password, password_length); - if (r < 0) - return r; + if (!strcmp(kdf, "pbkdf2")) { + r = crypt_hmac_init(&h, hash, password, password_length); + if (r < 0) + return r; + + nettle_pbkdf2(&h->nettle_ctx, h->hash->hmac_update, + h->hash->hmac_digest, h->hash->length, iterations, + salt_length, (const uint8_t *)salt, key_length, + (uint8_t *)key); + crypt_hmac_destroy(h); + return 0; + } 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; - nettle_pbkdf2(&h->nettle_ctx, h->hash->nettle_hmac_update, - h->hash->nettle_hmac_digest, h->hash->length, iterations, - salt_length, (const uint8_t *)salt, key_length, - (uint8_t *)key); - crypt_hmac_destroy(h); + 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) +{ + 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); +}