1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2019 IBM Corp. */
#ifndef pr_fmt
#define pr_fmt(fmt) "SECVAR: " fmt
#endif
#include <stdlib.h>
#include <string.h>
#include <skiboot.h>
#include <opal.h>
#include "secvar.h"
void clear_bank_list(struct list_head *bank)
{
struct secvar *var, *next;
if (!bank)
return;
list_for_each_safe(bank, var, next, link) {
list_del(&var->link);
dealloc_secvar(var);
}
}
int copy_bank_list(struct list_head *dst, struct list_head *src)
{
struct secvar *var, *tmp;
list_for_each(src, var, link) {
/* Allocate new secvar using actual data size */
tmp = new_secvar(var->key, var->key_len, var->data,
var->data_size, var->flags);
/* Append to new list */
list_add_tail(dst, &tmp->link);
}
return OPAL_SUCCESS;
}
struct secvar *alloc_secvar(uint64_t key_len, uint64_t data_size)
{
struct secvar *ret;
ret = zalloc(sizeof(struct secvar));
if (!ret)
return NULL;
ret->key = zalloc(key_len);
if (!ret->key) {
free(ret);
return NULL;
}
ret->data = zalloc(data_size);
if (!ret->data) {
free(ret->key);
free(ret);
return NULL;
}
ret->key_len = key_len;
ret->data_size = data_size;
return ret;
}
struct secvar *new_secvar(const char *key, uint64_t key_len,
const char *data, uint64_t data_size,
uint64_t flags)
{
struct secvar *ret;
if (!key)
return NULL;
if ((!key_len) || (key_len > SECVAR_MAX_KEY_LEN))
return NULL;
if ((!data) && (data_size))
return NULL;
ret = alloc_secvar(key_len, data_size);
if (!ret)
return NULL;
memcpy(ret->key, key, key_len);
ret->flags = flags;
if (data)
memcpy(ret->data, data, data_size);
return ret;
}
int realloc_secvar(struct secvar *var, uint64_t size)
{
void *tmp;
if (var->data_size >= size)
return 0;
tmp = zalloc(size);
if (!tmp)
return -1;
memcpy(tmp, var->data, var->data_size);
free(var->data);
var->data = tmp;
return 0;
}
void dealloc_secvar(struct secvar *var)
{
if (!var)
return;
free(var->key);
free(var->data);
free(var);
}
struct secvar *find_secvar(const char *key, uint64_t key_len, struct list_head *bank)
{
struct secvar *var = NULL;
list_for_each(bank, var, link) {
// Prevent matching shorter key subsets / bail early
if (key_len != var->key_len)
continue;
if (!memcmp(key, var->key, key_len))
return var;
}
return NULL;
}
int is_key_empty(const char *key, uint64_t key_len)
{
int i;
for (i = 0; i < key_len; i++) {
if (key[i] != 0)
return 0;
}
return 1;
}
int list_length(struct list_head *bank)
{
int ret = 0;
struct secvar *var;
list_for_each(bank, var, link)
ret++;
return ret;
}
|