diff options
Diffstat (limited to '')
| -rw-r--r-- | librecrypt_add_algorithm.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/librecrypt_add_algorithm.c b/librecrypt_add_algorithm.c new file mode 100644 index 0000000..a2d8aa4 --- /dev/null +++ b/librecrypt_add_algorithm.c @@ -0,0 +1,96 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +ssize_t +librecrypt_add_algorithm(char *out_buffer, size_t size, char *augend, const char *restrict augment, void *reserved) +{ + size_t prefix1 = librecrypt_settings_prefix(augend); + size_t prefix2, min, ret, len, phraselen; + char *phrase, pad; + int strict_pad; + const unsigned char *lut; + ssize_t r; + +#define COPY_PREFIX()\ + do {\ + size -= 1u;\ + min = prefix1 < size ? prefix1 : size;\ + if (out_buffer != augend)\ + memmove(out_buffer, augend, min);\ + out_buffer = &out_buffer[min];\ + size -= min;\ + if (size) {\ + *out_buffer++ = LIBRECRYPT_ALGORITHM_LINK_DELIMITER;\ + size -= 1u;\ + }\ + } while (0) + + if (!augend[prefix1]) { + prefix2 = librecrypt_settings_prefix(augment); + ret = prefix1 + 1u + prefix2; + if (size) { + COPY_PREFIX(); + min = prefix2 < size ? prefix2 : size; + memcpy(out_buffer, augment, min); + out_buffer[min] = '\0'; + } + return (ssize_t)ret; + } + + if (size <= prefix1 + 2u) { + phrase = NULL; + phraselen = 0u; + } else { + lut = librecrypt_get_encoding(augend, strlen(augend), &pad, &strict_pad, 1); + if (!lut) + return -1; + + len = strlen(&augend[prefix1]); + r = librecrypt_decode(NULL, 0, &augend[prefix1], len, lut, pad, strict_pad); + if (r <= 0) { + if (!r) + abort(); + return -1; + } + phraselen = (size_t)r; + phrase = malloc(phraselen); + if (!phrase) + return -1; + if (librecrypt_decode(phrase, phraselen, &augend[prefix1], len, lut, pad, strict_pad) != r) + abort(); + } + + COPY_PREFIX(); + ret = prefix1 + 1u; + r = librecrypt_crypt(out_buffer, size + 1u, phrase, phraselen, augment, reserved); + if (r <= 0) { + librecrypt_wipe(phrase, phraselen); + free(phrase); + if (!r) + abort(); + return -1; + } + ret += (size_t)r; + + librecrypt_wipe(phrase, phraselen); + free(phrase); + return (ssize_t)ret; +} + + +#else + + +int +main(void) +{ + SET_UP_ALARM(); + + return 0; +} + + +#endif +/* TODO test */ |
