X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fvolumekey.c;h=fafaec6cf5013dc4dda46f4cd6c41075ba411ce5;hb=690c363eb90277fc53a97e3e2367ebe12055937e;hp=9a80529e38980346e0b97b95f336a6747491f09a;hpb=d0b21614422d7ecd787aeffb894eba1a6973f4fa;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/lib/volumekey.c b/lib/volumekey.c index 9a80529..fafaec6 100644 --- a/lib/volumekey.c +++ b/lib/volumekey.c @@ -1,8 +1,8 @@ /* * cryptsetup volume key implementation * - * Copyright (C) 2004-2006, Clemens Fruhwirth - * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2006 Clemens Fruhwirth + * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,36 +20,116 @@ */ #include +#include #include +#include #include "internal.h" -struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key) +struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key) { - struct volume_key *vk = malloc(sizeof(*vk) + keylength); + struct volume_key *vk; + + if (keylength > (SIZE_MAX - sizeof(*vk))) + return NULL; + vk = malloc(sizeof(*vk) + keylength); if (!vk) return NULL; + vk->key_description = NULL; vk->keylength = keylength; - if (key) - memcpy(&vk->key, key, keylength); - else - memset(&vk->key, 0, keylength); + vk->id = -1; + vk->next = NULL; + + /* keylength 0 is valid => no key */ + if (vk->keylength) { + if (key) + memcpy(&vk->key, key, keylength); + else + crypt_safe_memzero(&vk->key, keylength); + } + + return vk; +} + +int crypt_volume_key_set_description(struct volume_key *vk, const char *key_description) +{ + if (!vk) + return -EINVAL; + + free(CONST_CAST(void*)vk->key_description); + vk->key_description = NULL; + if (key_description && !(vk->key_description = strdup(key_description))) + return -ENOMEM; + + return 0; +} + +void crypt_volume_key_set_id(struct volume_key *vk, int id) +{ + if (vk && id >= 0) + vk->id = id; +} + +int crypt_volume_key_get_id(const struct volume_key *vk) +{ + return vk ? vk->id : -1; +} + +struct volume_key *crypt_volume_key_by_id(struct volume_key *vks, int id) +{ + struct volume_key *vk = vks; + + if (id < 0) + return NULL; + + while (vk && vk->id != id) + vk = vk->next; return vk; } +void crypt_volume_key_add_next(struct volume_key **vks, struct volume_key *vk) +{ + struct volume_key *tmp; + + if (!vks) + return; + + if (!*vks) { + *vks = vk; + return; + } + + tmp = *vks; + + while (tmp->next) + tmp = tmp->next; + + tmp->next = vk; +} + +struct volume_key *crypt_volume_key_next(struct volume_key *vk) +{ + return vk ? vk->next : NULL; +} + void crypt_free_volume_key(struct volume_key *vk) { - if (vk) { - memset(vk->key, 0, vk->keylength); + struct volume_key *vk_next; + + while (vk) { + crypt_safe_memzero(vk->key, vk->keylength); vk->keylength = 0; + free(CONST_CAST(void*)vk->key_description); + vk_next = vk->next; free(vk); + vk = vk_next; } } -struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength) +struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength) { int r; struct volume_key *vk;