| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2005-2010 IBM Corporation |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Mimi Zohar <zohar@us.ibm.com> |
|---|
| 6 | 7 | * Kylene Hall <kjhall@us.ibm.com> |
|---|
| 7 | 8 | * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation, version 2 of the License. |
|---|
| 11 | | - * |
|---|
| 12 | 9 | * File: evm_crypto.c |
|---|
| 13 | 10 | * Using root's kernel master key (kmk), calculate the HMAC |
|---|
| 14 | 11 | */ |
|---|
| 15 | 12 | |
|---|
| 16 | | -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| 17 | | - |
|---|
| 18 | | -#include <linux/module.h> |
|---|
| 13 | +#include <linux/export.h> |
|---|
| 19 | 14 | #include <linux/crypto.h> |
|---|
| 20 | 15 | #include <linux/xattr.h> |
|---|
| 21 | 16 | #include <linux/evm.h> |
|---|
| .. | .. |
|---|
| 27 | 22 | #define EVMKEY "evm-key" |
|---|
| 28 | 23 | #define MAX_KEY_SIZE 128 |
|---|
| 29 | 24 | static unsigned char evmkey[MAX_KEY_SIZE]; |
|---|
| 30 | | -static int evmkey_len = MAX_KEY_SIZE; |
|---|
| 25 | +static const int evmkey_len = MAX_KEY_SIZE; |
|---|
| 31 | 26 | |
|---|
| 32 | 27 | struct crypto_shash *hmac_tfm; |
|---|
| 33 | 28 | static struct crypto_shash *evm_tfm[HASH_ALGO__LAST]; |
|---|
| .. | .. |
|---|
| 38 | 33 | |
|---|
| 39 | 34 | static unsigned long evm_set_key_flags; |
|---|
| 40 | 35 | |
|---|
| 41 | | -static char * const evm_hmac = "hmac(sha1)"; |
|---|
| 36 | +static const char evm_hmac[] = "hmac(sha1)"; |
|---|
| 42 | 37 | |
|---|
| 43 | 38 | /** |
|---|
| 44 | 39 | * evm_set_key() - set EVM HMAC key from the kernel |
|---|
| .. | .. |
|---|
| 78 | 73 | { |
|---|
| 79 | 74 | long rc; |
|---|
| 80 | 75 | const char *algo; |
|---|
| 81 | | - struct crypto_shash **tfm; |
|---|
| 76 | + struct crypto_shash **tfm, *tmp_tfm; |
|---|
| 82 | 77 | struct shash_desc *desc; |
|---|
| 83 | 78 | |
|---|
| 84 | 79 | if (type == EVM_XATTR_HMAC) { |
|---|
| .. | .. |
|---|
| 96 | 91 | algo = hash_algo_name[hash_algo]; |
|---|
| 97 | 92 | } |
|---|
| 98 | 93 | |
|---|
| 99 | | - if (IS_ERR_OR_NULL(*tfm)) { |
|---|
| 100 | | - mutex_lock(&mutex); |
|---|
| 101 | | - if (*tfm) |
|---|
| 102 | | - goto out; |
|---|
| 103 | | - *tfm = crypto_alloc_shash(algo, 0, |
|---|
| 104 | | - CRYPTO_ALG_ASYNC | CRYPTO_NOLOAD); |
|---|
| 105 | | - if (IS_ERR(*tfm)) { |
|---|
| 106 | | - rc = PTR_ERR(*tfm); |
|---|
| 107 | | - pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); |
|---|
| 108 | | - *tfm = NULL; |
|---|
| 94 | + if (*tfm) |
|---|
| 95 | + goto alloc; |
|---|
| 96 | + mutex_lock(&mutex); |
|---|
| 97 | + if (*tfm) |
|---|
| 98 | + goto unlock; |
|---|
| 99 | + |
|---|
| 100 | + tmp_tfm = crypto_alloc_shash(algo, 0, CRYPTO_NOLOAD); |
|---|
| 101 | + if (IS_ERR(tmp_tfm)) { |
|---|
| 102 | + pr_err("Can not allocate %s (reason: %ld)\n", algo, |
|---|
| 103 | + PTR_ERR(tmp_tfm)); |
|---|
| 104 | + mutex_unlock(&mutex); |
|---|
| 105 | + return ERR_CAST(tmp_tfm); |
|---|
| 106 | + } |
|---|
| 107 | + if (type == EVM_XATTR_HMAC) { |
|---|
| 108 | + rc = crypto_shash_setkey(tmp_tfm, evmkey, evmkey_len); |
|---|
| 109 | + if (rc) { |
|---|
| 110 | + crypto_free_shash(tmp_tfm); |
|---|
| 109 | 111 | mutex_unlock(&mutex); |
|---|
| 110 | 112 | return ERR_PTR(rc); |
|---|
| 111 | 113 | } |
|---|
| 112 | | - if (type == EVM_XATTR_HMAC) { |
|---|
| 113 | | - rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len); |
|---|
| 114 | | - if (rc) { |
|---|
| 115 | | - crypto_free_shash(*tfm); |
|---|
| 116 | | - *tfm = NULL; |
|---|
| 117 | | - mutex_unlock(&mutex); |
|---|
| 118 | | - return ERR_PTR(rc); |
|---|
| 119 | | - } |
|---|
| 120 | | - } |
|---|
| 121 | | -out: |
|---|
| 122 | | - mutex_unlock(&mutex); |
|---|
| 123 | 114 | } |
|---|
| 124 | | - |
|---|
| 115 | + *tfm = tmp_tfm; |
|---|
| 116 | +unlock: |
|---|
| 117 | + mutex_unlock(&mutex); |
|---|
| 118 | +alloc: |
|---|
| 125 | 119 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), |
|---|
| 126 | 120 | GFP_KERNEL); |
|---|
| 127 | 121 | if (!desc) |
|---|
| 128 | 122 | return ERR_PTR(-ENOMEM); |
|---|
| 129 | 123 | |
|---|
| 130 | 124 | desc->tfm = *tfm; |
|---|
| 131 | | - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
|---|
| 132 | 125 | |
|---|
| 133 | 126 | rc = crypto_shash_init(desc); |
|---|
| 134 | 127 | if (rc) { |
|---|
| .. | .. |
|---|
| 177 | 170 | crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); |
|---|
| 178 | 171 | if ((evm_hmac_attrs & EVM_ATTR_FSUUID) && |
|---|
| 179 | 172 | type != EVM_XATTR_PORTABLE_DIGSIG) |
|---|
| 180 | | - crypto_shash_update(desc, &inode->i_sb->s_uuid.b[0], |
|---|
| 181 | | - sizeof(inode->i_sb->s_uuid)); |
|---|
| 173 | + crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE); |
|---|
| 182 | 174 | crypto_shash_final(desc, digest); |
|---|
| 183 | 175 | } |
|---|
| 184 | 176 | |
|---|