int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, const void *buffer, size_t length) { struct crypt_hmac *h; h = malloc(sizeof(*h)); if (!h) return -ENOMEM; memset(ctx, 0, sizeof(*ctx)); h->hash = _get_alg(name); if (!h->hash) goto bad; h->key = malloc(length); if (!h->key) goto bad; memcpy(h->key, buffer, length); h->key_length = length; h->hash->init(&h->nettle_ctx); h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key); *ctx = h; return 0; bad: free(h); return -EINVAL; }
/* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, uint32_t iterations, uint32_t memory, uint32_t parallel) { struct hash_alg *ha; if (!kdf) return -EINVAL; if (!strcmp(kdf, "pbkdf2")) { ha = _get_alg(hash); if (!ha) return -EINVAL; return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, iterations, key_length, key, ha->block_length); } else if (!strncmp(kdf, "argon2", 6)) { return argon2(kdf, password, password_length, salt, salt_length, key, key_length, iterations, memory, parallel); } return -EINVAL; }
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, const void *buffer, size_t length) { struct crypt_hmac *h; struct hash_alg *ha; struct sockaddr_alg sa = { .salg_family = AF_ALG, .salg_type = "hash", }; h = malloc(sizeof(*h)); if (!h) return -ENOMEM; ha = _get_alg(name); if (!ha) { free(h); return -EINVAL; } h->hash_len = ha->length; snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "hmac(%s)", ha->kernel_name); if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) { free(h); return -EINVAL; } if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) { crypt_hmac_destroy(h); return -EINVAL; } *ctx = h; return 0; } int crypt_hmac_restart(struct crypt_hmac *ctx) { return 0; } int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length) { ssize_t r; r = send(ctx->opfd, buffer, length, MSG_MORE); if (r < 0 || (size_t)r < length) return -EIO; return 0; }
/* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, unsigned int iterations) { struct hash_alg *ha = _get_alg(hash); if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6)) return -EINVAL; return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, iterations, key_length, key, ha->block_length); }
int crypt_hash_init(struct crypt_hash **ctx, const char *name) { struct crypt_hash *h; struct hash_alg *ha; struct sockaddr_alg sa = { .salg_family = AF_ALG, .salg_type = "hash", }; h = malloc(sizeof(*h)); if (!h) return -ENOMEM; ha = _get_alg(name); if (!ha) { free(h); return -EINVAL; } h->hash_len = ha->length; strncpy((char *)sa.salg_name, ha->kernel_name, sizeof(sa.salg_name)); if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) { free(h); return -EINVAL; } *ctx = h; return 0; } int crypt_hash_restart(struct crypt_hash *ctx) { return 0; } int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length) { ssize_t r; r = send(ctx->opfd, buffer, length, MSG_MORE); if (r < 0 || (size_t)r < length) return -EIO; return 0; }
int crypt_hash_init(struct crypt_hash **ctx, const char *name) { struct crypt_hash *h; h = malloc(sizeof(*h)); if (!h) return -ENOMEM; h->hash = _get_alg(name); if (!h->hash) { free(h); return -EINVAL; } h->hash->init(&h->nettle_ctx); *ctx = h; return 0; }
/* HASH */ int crypt_hash_size(const char *name) { struct hash_alg *ha = _get_alg(name); return ha ? ha->length : -EINVAL; }