Merge "Merge branch 'upstream' into tizen" into tizen
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_nss.c
index 4b9f943..7e4db80 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * NSS crypto backend implementation
  *
- * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
- * Copyright (C) 2010-2014, Milan Broz
+ * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2010-2021 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,7 +23,7 @@
 #include <errno.h>
 #include <nss.h>
 #include <pk11pub.h>
-#include "crypto_backend.h"
+#include "crypto_backend_internal.h"
 
 #define CONST_CAST(x) (x)(uintptr_t)
 
@@ -59,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;
@@ -71,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(void)
 {
+       int r;
+
        if (crypto_backend_initialised)
                return 0;
 
@@ -80,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;
@@ -175,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 */
@@ -190,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;
@@ -277,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);
@@ -287,7 +300,6 @@ int crypt_hmac_destroy(struct crypt_hmac *ctx)
                PK11_DestroyContext(ctx->md, PR_TRUE);
        memset(ctx, 0, sizeof(*ctx));
        free(ctx);
-       return 0;
 }
 
 /* RNG */
@@ -307,13 +319,79 @@ 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 hash_alg *ha = _get_alg(hash);
+       struct hash_alg *ha;
 
-       if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6))
+       if (!kdf)
                return -EINVAL;
 
-       return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
-                           iterations, key_length, key, ha->block_length);
+       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)
+{
+       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);
 }