kernel_lib.h 7.3 KB
Newer Older
R
Roberto Sassu 已提交
1 2
/*
 * Copyright (C) 1991, 1992 Linus Torvalds
R
Roberto Sassu 已提交
3 4
 * Copyright (C) 2002 Nadia Yvette Chambers, IBM
 * Copyright (C) 2007 rPath, Inc. - All Rights Reserved
R
Roberto Sassu 已提交
5
 * Copyright (c) 2013 Dmitry Kasatkin <d.kasatkin@samsung.com>
R
Roberto Sassu 已提交
6
 * Copyright (C) 2017-2020 Huawei Technologies Duesseldorf GmbH
R
Roberto Sassu 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * Author: Roberto Sassu <roberto.sassu@huawei.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 2 of the
 * License.
 *
 * File: kernel_lib.h
 *      Header of kernel_lib.c
 */

#ifndef _KERNEL_LIB_H
#define _KERNEL_LIB_H

#include <stdio.h>
#include <stdlib.h>
R
Roberto Sassu 已提交
24
#include <stdint.h>
R
Roberto Sassu 已提交
25 26
#include <ctype.h>
#include <string.h>
R
Roberto Sassu 已提交
27 28 29 30 31
#include <fcntl.h>
#include <linux/xattr.h>
#ifdef __BIG_ENDIAN__
#include <linux/byteorder/big_endian.h>
#else
R
Roberto Sassu 已提交
32
#include <linux/byteorder/little_endian.h>
R
Roberto Sassu 已提交
33
#endif
34
#include <asm/bitsperlong.h>
R
Roberto Sassu 已提交
35 36

#include "list.h"
R
Roberto Sassu 已提交
37 38 39 40 41 42

/* kernel types */
typedef u_int8_t u8;
typedef u_int16_t u16;
typedef u_int32_t u32;
typedef u_int64_t u64;
R
Roberto Sassu 已提交
43
#ifndef bool
R
Roberto Sassu 已提交
44
typedef int bool;
R
Roberto Sassu 已提交
45 46 47 48 49 50
#endif

typedef unsigned long atomic_long_t;

static inline void atomic_long_inc(atomic_long_t *x)
{
A
Anakin Zhang 已提交
51
    (*x)++;
R
Roberto Sassu 已提交
52
}
R
Roberto Sassu 已提交
53 54 55 56

#define true 1
#define false 0

R
Roberto Sassu 已提交
57 58
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))

R
Roberto Sassu 已提交
59 60
#define S_IWUGO         (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO         (S_IXUSR|S_IXGRP|S_IXOTH)
R
Roberto Sassu 已提交
61 62

#define pr_err printf
R
Roberto Sassu 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75
#define pr_info printf

#ifdef DEBUG
#define pr_devel printf
#define pr_debug printf
#else
static inline void pr_devel(const char *__restrict __format, ...)
{
}
static inline void pr_debug(const char *__restrict __format, ...)
{
}
#endif /* DEBUG */
R
Roberto Sassu 已提交
76

R
Roberto Sassu 已提交
77 78 79 80 81 82
#define rcu_read_lock()
#define rcu_read_unlock()

#define GFP_KERNEL 0
#define kmalloc(x, y) malloc(x)

R
Roberto Sassu 已提交
83 84 85
/* endianness conversion */
#define be32_to_cpu __be32_to_cpu
#define be16_to_cpu __be16_to_cpu
R
Roberto Sassu 已提交
86 87
#define cpu_to_be32 __cpu_to_be32
#define cpu_to_be16 __cpu_to_be16
R
Roberto Sassu 已提交
88 89
#define le16_to_cpu __le16_to_cpu
#define le32_to_cpu __le32_to_cpu
R
Roberto Sassu 已提交
90
#define le64_to_cpu __le64_to_cpu
R
Roberto Sassu 已提交
91 92
#define cpu_to_le16 __cpu_to_le16
#define cpu_to_le32 __cpu_to_le32
R
Roberto Sassu 已提交
93
#define cpu_to_le64 __cpu_to_le64
R
Roberto Sassu 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

/* crypto */
#define CRYPTO_MAX_ALG_NAME             128

#define MD5_DIGEST_SIZE         16
#define SHA1_DIGEST_SIZE        20
#define RMD160_DIGEST_SIZE      20
#define SHA256_DIGEST_SIZE      32
#define SHA384_DIGEST_SIZE      48
#define SHA512_DIGEST_SIZE      64
#define SHA224_DIGEST_SIZE      28
#define RMD128_DIGEST_SIZE      16
#define RMD256_DIGEST_SIZE      32
#define RMD320_DIGEST_SIZE      40
#define WP512_DIGEST_SIZE 64
#define WP384_DIGEST_SIZE 48
#define WP256_DIGEST_SIZE 32
#define TGR192_DIGEST_SIZE 24
#define TGR160_DIGEST_SIZE 20
#define TGR128_DIGEST_SIZE 16
#define SM3256_DIGEST_SIZE 32

enum hash_algo {
A
Anakin Zhang 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    HASH_ALGO_MD4,
    HASH_ALGO_MD5,
    HASH_ALGO_SHA1,
    HASH_ALGO_RIPE_MD_160,
    HASH_ALGO_SHA256,
    HASH_ALGO_SHA384,
    HASH_ALGO_SHA512,
    HASH_ALGO_SHA224,
    HASH_ALGO_RIPE_MD_128,
    HASH_ALGO_RIPE_MD_256,
    HASH_ALGO_RIPE_MD_320,
    HASH_ALGO_WP_256,
    HASH_ALGO_WP_384,
    HASH_ALGO_WP_512,
    HASH_ALGO_TGR_128,
    HASH_ALGO_TGR_160,
    HASH_ALGO_TGR_192,
    HASH_ALGO_SM3_256,
    HASH_ALGO__LAST
R
Roberto Sassu 已提交
136 137
};

R
Roberto Sassu 已提交
138
/* from crypto/hash_info.c */
R
Roberto Sassu 已提交
139 140 141
extern const char *const hash_algo_name[HASH_ALGO__LAST];
extern const int hash_digest_size[HASH_ALGO__LAST];

R
Roberto Sassu 已提交
142
/* hash */
143
#if __BITB_PER_LONG == 32
R
Roberto Sassu 已提交
144 145
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
#define hash_long(val, bits) hash_32(val, bits)
146
#elif __BITS_PER_LONG == 64
R
Roberto Sassu 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160
#define hash_long(val, bits) hash_64(val, bits)
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
#else
#error Wordsize not 32 or 64
#endif

#define GOLDEN_RATIO_32 0x61C88647
#define GOLDEN_RATIO_64 0x61C8864680B583EBull

#ifndef HAVE_ARCH__HASH_32
#define __hash_32 __hash_32_generic
#endif
static inline u32 __hash_32_generic(u32 val)
{
A
Anakin Zhang 已提交
161
    return val * GOLDEN_RATIO_32;
R
Roberto Sassu 已提交
162 163 164 165 166 167 168
}

#ifndef HAVE_ARCH_HASH_32
#define hash_32 hash_32_generic
#endif
static inline u32 hash_32_generic(u32 val, unsigned int bits)
{
A
Anakin Zhang 已提交
169 170
    /* High bits are more random, so use them. */
    return __hash_32(val) >> (32 - bits);
R
Roberto Sassu 已提交
171 172 173 174 175 176 177 178
}

#ifndef HAVE_ARCH_HASH_64
#define hash_64 hash_64_generic
#endif
static __always_inline u32 hash_64_generic(u64 val, unsigned int bits)
{
#if BITS_PER_LONG == 64
A
Anakin Zhang 已提交
179 180
    /* 64x64-bit multiply is efficient on all 64-bit processors */
    return val * GOLDEN_RATIO_64 >> (64 - bits);
R
Roberto Sassu 已提交
181
#else
A
Anakin Zhang 已提交
182 183
    /* Hash 64 bits using only 32x32-bit multiply. */
    return hash_32((u32)val ^ __hash_32(val >> 32), bits);
R
Roberto Sassu 已提交
184 185 186 187 188
#endif
}

static inline u32 hash_ptr(const void *ptr, unsigned int bits)
{
A
Anakin Zhang 已提交
189
    return hash_long((unsigned long)ptr, bits);
R
Roberto Sassu 已提交
190 191 192 193 194
}

/* This really should be called fold32_ptr; it does no hashing to speak of. */
static inline u32 hash32_ptr(const void *ptr)
{
A
Anakin Zhang 已提交
195
    unsigned long val = (unsigned long)ptr;
R
Roberto Sassu 已提交
196

197
#if __BITS_PER_LONG == 64
A
Anakin Zhang 已提交
198
    val ^= (val >> 32);
R
Roberto Sassu 已提交
199
#endif
A
Anakin Zhang 已提交
200
    return (u32)val;
R
Roberto Sassu 已提交
201 202
}

R
Roberto Sassu 已提交
203
/* from kernel.h */
R
Roberto Sassu 已提交
204 205
int hex2bin(u8 *dst, const char *src, size_t count);

R
Roberto Sassu 已提交
206
/* from xattr.h */
R
Roberto Sassu 已提交
207 208 209
#define XATTR_IMA_ALGO_SUFFIX "ima_algo"
#define XATTR_NAME_IMA_ALGO XATTR_SECURITY_PREFIX XATTR_IMA_ALGO_SUFFIX

R
Roberto Sassu 已提交
210 211 212
/* from ima.h */
extern bool ima_canonical_fmt;

R
Roberto Sassu 已提交
213 214 215 216 217
#define IMA_HASH_BITS 9
#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)

static inline unsigned long ima_hash_key(u8 *digest)
{
A
Anakin Zhang 已提交
218
    return hash_long(*digest, IMA_HASH_BITS);
R
Roberto Sassu 已提交
219 220 221
}

struct ima_h_table {
A
Anakin Zhang 已提交
222 223 224
    atomic_long_t len;	/* number of stored measurements in the list */
    atomic_long_t violations;
    struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
R
Roberto Sassu 已提交
225 226
};

R
Roberto Sassu 已提交
227 228
/* from integrity.h */
enum evm_ima_xattr_type {
A
Anakin Zhang 已提交
229 230 231 232 233 234 235
    IMA_XATTR_DIGEST = 0x01,
    EVM_XATTR_HMAC,
    EVM_IMA_XATTR_DIGSIG,
    IMA_XATTR_DIGEST_NG,
    EVM_XATTR_PORTABLE_DIGSIG,
    EVM_IMA_XATTR_DIGEST_LIST,
    IMA_XATTR_LAST
R
Roberto Sassu 已提交
236 237 238
};

enum evm_ima_sig_fmt {
A
Anakin Zhang 已提交
239 240 241
    SIG_FMT_IMA,
    SIG_FMT_PGP,
    SIG_FMT__LAST,
R
Roberto Sassu 已提交
242 243 244
};

struct signature_v2_hdr {
A
Anakin Zhang 已提交
245 246 247 248 249 250
    uint8_t type;		/* xattr type */
    uint8_t version;	/* signature format version */
    uint8_t	hash_algo;	/* Digest algorithm [enum hash_algo] */
    __be32 keyid;		/* IMA key identifier - not X509/PGP specific */
    __be16 sig_size;	/* signature size */
    uint8_t sig[0];		/* signature payload */
R
Roberto Sassu 已提交
251 252
} __attribute__((packed));

R
Roberto Sassu 已提交
253
struct evm_ima_xattr_data {
A
Anakin Zhang 已提交
254 255
    uint8_t type;
    uint8_t digest[SHA512_DIGEST_SIZE + 1];
R
Roberto Sassu 已提交
256 257
} __attribute__((packed));

R
Roberto Sassu 已提交
258
/* from integrity.h */
R
Roberto Sassu 已提交
259
enum compact_types { COMPACT_KEY, COMPACT_PARSER, COMPACT_FILE,
A
Anakin Zhang 已提交
260
             COMPACT_METADATA, COMPACT__LAST };
R
Roberto Sassu 已提交
261 262 263
enum compact_modifiers { COMPACT_MOD_IMMUTABLE, COMPACT_MOD__LAST };

struct ima_digest {
A
Anakin Zhang 已提交
264 265 266 267 268 269
    struct hlist_node hnext;
    struct list_head list;
    enum hash_algo algo;
    enum compact_types type;
    u16 modifiers;
    u8 digest[0];
R
Roberto Sassu 已提交
270 271 272 273
};

/* from ima_digest_list.c */
struct compact_list_hdr {
A
Anakin Zhang 已提交
274 275 276 277 278 279 280
    u8 version;
    u8 _reserved;
    u16 type;
    u16 modifiers;
    u16 algo;
    u32 count;
    u32 datalen;
R
Roberto Sassu 已提交
281 282 283
} __attribute__((packed));

typedef int (*add_digest_func)(u8 *digest, enum hash_algo algo,
A
Anakin Zhang 已提交
284
                   enum compact_types type, u16 modifiers);
R
Roberto Sassu 已提交
285 286 287 288 289

int default_func(u8 *digest, enum hash_algo algo, enum compact_types type,
                 u16 modifiers);

int ima_parse_compact_list(loff_t size, void *buf,
A
Anakin Zhang 已提交
290 291
               add_digest_func ima_add_digest_data_entry,
               enum hash_algo *algo);
R
Roberto Sassu 已提交
292 293 294

struct ima_digest *ima_lookup_digest(u8 *digest, enum hash_algo algo);
int ima_add_digest_data_entry_kernel(u8 *digest, enum hash_algo algo,
A
Anakin Zhang 已提交
295
                     enum compact_types type, u16 modifiers);
R
Roberto Sassu 已提交
296

R
Roberto Sassu 已提交
297
#endif /* _KERNEL_LIB_H */