/*
* 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
#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)
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;
return NULL;
}
-int crypt_backend_init(struct crypt_device *ctx)
+int crypt_backend_init(void)
{
+ int r;
+
if (crypto_backend_initialised)
return 0;
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;
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 */
}
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;
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);
PK11_DestroyContext(ctx->md, PR_TRUE);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
- return 0;
}
/* RNG */
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);
}