libkcapi

libkcapi 是 kernel 推荐的用户层接口,X5 支持使用 libkcapi 库调用以下算法类型:hashcipher 以及 aead。下面对 libkcapi API 的介绍摘录自 kcapi.h,详细内容可到下面链接中了解。

kcapi官网: https://www.chronox.de/libkcapi/libkcapi.html

kcapi git: https://github.com/smuellerDD/libkcapi

kernel介绍: https://www.kernel.org/doc/html/v5.10/crypto/userspace-if.html

对称算法

对称算法通过调用libkcapi库,完成加解密操作。头文件kcapi.h,版本为1.1.5。

API参考

kcapi_cipher_init : 初始化接口
kcapi_cipher_destroy : 释放资源接口
kcapi_cipher_setkey : 设置密钥接口
kcapi_cipher_encrypt : 加密接口
kcapi_cipher_decrypt : 解密接口

接口说明

kcapi_cipher_init

【函数声明】

int kcapi_cipher_init(struct kcapi_handle **handle, const char *ciphername,
        uint32_t flags);

【功能描述】

用于初始化一个 cipher 上下文

【参数描述】

  • [OUT] struct kcapi_handle **handle : 指向 kcapi_handle 结构体的指针,表示一个加密算法的实例

  • [OUT] char *ciphername : cipher 名称

  • [IN] uint32_t flags : 指定 cipher 句柄的类型的标志

【返回值】

  • 成功,返回 0

  • 失败:非零异常值

    • -ENOENT - 加密算法不可用

    • -EOPNOTSUPP - AF_ALG family 不可用

    • -EINVAL - accept syscall 调用失败

    • -ENOMEM - 无法创建加密句柄

kcapi_cipher_destroy

【函数声明】

void kcapi_cipher_destroy(struct kcapi_handle *handle);

【功能描述】

关闭加密句柄,并释放资源

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

【返回值】

kcapi_cipher_setkey

【函数声明】

int kcapi_cipher_setkey(struct kcapi_handle *handle,
   const uint8_t *key, uint32_t keylen);

【功能描述】

设置加解密操作所需的密钥

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *key : 密钥 buffer

  • [IN] uint32_t keylen : 密钥长度

【返回值】

  • 成功,返回 0

  • 失败:非零

kcapi_cipher_encrypt

【函数声明】

int32_t kcapi_cipher_encrypt(struct kcapi_handle *handle,
        const uint8_t *in, uint32_t inlen,
        const uint8_t *iv,
        uint8_t *out, uint32_t outlen, int access);

【功能描述】

执行加密操作

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *in : 明文 buffer

  • [IN] uint32_t inlen : 明文长度

  • [IN] uint8_t *iv : 保存 iv 的 buffer

  • [OUT] uint8_t *out : 密文 buffer

  • [OUT] uint32_t outlen : 密文长度

  • [INT] int access : 内核访问类型

    • KCAPI_ACCESS_HEURISTIC - 使用内部启发式方法以实现最快的内核访问

    • KCAPI_ACCESS_VMSPLICE - 通过 vmsplice 访问

    • KCAPI_ACCESS_SENDMSG - 通过 sendmsg 访问

【返回值】

  • 加密成功的字节数

kcapi_cipher_decrypt

【函数声明】

int32_t kcapi_cipher_decrypt(struct kcapi_handle *handle,
        const uint8_t *in, uint32_t inlen,
        const uint8_t *iv,
        uint8_t *out, uint32_t outlen, int access);

【功能描述】

执行解密操作

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *in : 密文 buffer

  • [IN] uint32_t inlen : 密文长度

  • [IN] uint8_t *iv : 保存 iv 的 buffer

  • [OUT] uint8_t *out : 明文 buffer

  • [OUT] uint32_t outlen : 明文长度

  • [INT] int access : 内核访问类型

    • KCAPI_ACCESS_HEURISTIC - 使用内部启发式方法以实现最快的内核访问

    • KCAPI_ACCESS_VMSPLICE - 通过 vmsplice 访问

    • KCAPI_ACCESS_SENDMSG - 通过 sendmsg 访问

【返回值】

  • 解密成功的字节数

使用示例

ssize_t test_cipher(const char *name,
                const uint8_t *key, uint32_t keylen,
                const uint8_t *in, size_t inlen,
                const uint8_t *iv,
                uint8_t *out, size_t outlen)
{
        struct kcapi_handle *handle;
        ssize_t ret = kcapi_cipher_init(&handle, name, 0);
        if (ret)
                return ret;
        ret = kcapi_cipher_setkey(handle, key, keylen);
        if (ret)
                goto out;
        ret = kcapi_cipher_encrypt(handle, in, inlen, iv, out, outlen, 0);
out:
        kcapi_cipher_destroy(handle);
        return ret;
}

HASH算法

HASH算法通过调用libkcapi库,完成计算hash操作。头文件kcapi.h,版本为1.1.5。

API参考

kcapi_md_init : 初始化接口
kcapi_md_destroy : 释放资源接口
kcapi_md_update : 消息摘要 update 接口
kcapi_md_final : 消息摘要结束接口

kcapi_md_init

【函数声明】

int kcapi_md_init(struct kcapi_handle **handle, const char *ciphername,
    uint32_t flags);

【功能描述】

用于初始化一个 cipher 上下文

【参数描述】

  • [OUT] struct kcapi_handle **handle : 指向 kcapi_handle 结构体的指针,表示一个加密算法的实例

  • [OUT] char *ciphername : cipher 名称

  • [IN] uint32_t flags : 指定 cipher 句柄的类型的标志

【返回值】

  • 成功,返回 0

  • 失败:非零异常值

    • -ENOENT - 加密算法不可用

    • -EOPNOTSUPP - AF_ALG family 不可用

    • -EINVAL - accept syscall 调用失败

    • -ENOMEM - 无法创建加密句柄

kcapi_md_destroy

【函数声明】

void kcapi_md_destroy(struct kcapi_handle *handle);

【功能描述】

关闭 cipher 句柄,并释放资源

【参数描述】

  • [IN] struct kcapi_handle *handle : cipher 句柄

【返回值】

kcapi_md_update

【函数声明】

int32_t kcapi_md_update(struct kcapi_handle *handle,
   const uint8_t *buffer, uint32_t len);

【功能描述】

更新消息摘要

【参数描述】

  • [IN] struct kcapi_handle *handle : cipher 句柄

  • [IN] uint8_t *buffer : 添加到计算消息摘要的数据 buffer

  • [IN] uint32_t len : 数据 buffer 长度

【返回值】

  • 成功,返回 0

  • 失败:非零

kcapi_md_final

【函数声明】

int32_t kcapi_md_final(struct kcapi_handle *handle,
         uint8_t *buffer, uint32_t len);

【功能描述】

更新消息摘要

【参数描述】

  • [IN] struct kcapi_handle *handle : cipher 句柄

  • [OUT] uint8_t *buffer : 消息摘要 buffer

  • [IN] uint32_t len : buffer 长度

【返回值】

  • 成功计算消息摘要的长度

使用示例

int test_hash(const char *name,
                const uint8_t *in, uint32_t inlen,
                uint8_t *out, uint32_t outlen)
{
        struct kcapi_handle *handle;
        int32_t ret = kcapi_md_init(&handle, name, 0);
        if (ret)
                return ret;

        ret = kcapi_md_update(handle, in, inlen);
        if (0 > ret)
                goto out;
        ret = kcapi_md_final(handle, out, outlen);
        if (0 > ret)
                goto out;
out:
        kcapi_md_destroy(handle);
        return ret;
}

AEAD算法

AEAD算法通过调用libkcapi库,完成加解密操作。头文件kcapi.h,版本为1.1.5。

API参考

kcapi_aead_init : 初始化接口
kcapi_aead_destroy : 释放资源接口
kcapi_aead_setkey : 设置密钥接口
kcapi_aead_settaglen : 设置加密tag len接口
kcapi_aead_setassoclen : 设置assoclen接口
kcapi_aead_encrypt : 加密接口
kcapi_aead_decrypt : 解密接口

kcapi_aead_init

【函数声明】

int kcapi_aead_init(struct kcapi_handle **handle, const char *ciphername,
    uint32_t flags);

【功能描述】

用于初始化一个 cipher 上下文

【参数描述】

  • [OUT] struct kcapi_handle **handle : 指向 kcapi_handle 结构体的指针,表示一个加密算法的实例

  • [OUT] char *ciphername : cipher 名称

  • [IN] uint32_t flags : 指定 cipher 句柄的类型的标志

【返回值】

  • 成功,返回 0

  • 失败:非零异常值

    • -ENOENT - 加密算法不可用

    • -EOPNOTSUPP - AF_ALG family 不可用

    • -EINVAL - accept syscall 调用失败

    • -ENOMEM - 无法创建加密句柄

kcapi_aead_destroy

【函数声明】

void kcapi_aead_destroy(struct kcapi_handle *handle);

【功能描述】

关闭 cipher 句柄,并释放资源

【参数描述】

  • [IN] struct kcapi_handle *handle : cipher 句柄

【返回值】

kcapi_aead_setkey

【函数声明】

int kcapi_aead_setkey(struct kcapi_handle *handle,
        const uint8_t *key, uint32_t keylen);

【功能描述】

设置加解密操作所需的密钥

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *key : 密钥 buffer

  • [IN] uint32_t keylen : 密钥长度

【返回值】

  • 成功,返回 0

  • 失败:非零

kcapi_aead_settaglen

【函数声明】

int kcapi_aead_settaglen(struct kcapi_handle *handle, uint32_t taglen);

【功能描述】

设置 aead 操作的授权 TAG 的长度

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint32_t taglen : 授权 TAG 的长度

【返回值】

  • 成功,返回 0

  • 失败:非零

kcapi_aead_setassoclen

【函数声明】

void kcapi_aead_setassoclen(struct kcapi_handle *handle, uint32_t assoclen);

【功能描述】

设置 aead 操作的关联数据的长度,关联数据不会被加密,但会参与身份验证

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint32_t assoclen : 授权 TAG 的长度

【返回值】

  • 成功,返回 0

  • 失败:非零

kcapi_aead_encrypt

【函数声明】

int32_t kcapi_aead_encrypt(struct kcapi_handle *handle,
      const uint8_t *in, uint32_t inlen,
      const uint8_t *iv,
      uint8_t *out, uint32_t outlen,
      int access);

【功能描述】

执行加密操作

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *in : 明文 buffer

  • [IN] uint32_t inlen : 明文长度

  • [IN] uint8_t *iv : 保存 iv 的 buffer

  • [OUT] uint8_t *out : 密文 buffer

  • [OUT] uint32_t outlen : 密文长度

  • [INT] int access : 内核访问类型

    • KCAPI_ACCESS_HEURISTIC - 使用内部启发式方法以实现最快的内核访问

    • KCAPI_ACCESS_VMSPLICE - 通过 vmsplice 访问

    • KCAPI_ACCESS_SENDMSG - 通过sendmsg 访问

【返回值】

  • 加密成功的字节数

kcapi_aead_decrypt

【函数声明】

int32_t kcapi_aead_decrypt(struct kcapi_handle *handle,
      const uint8_t *in, uint32_t inlen,
      const uint8_t *iv,
      uint8_t *out, uint32_t outlen, int access);

【功能描述】

执行解密操作

【参数描述】

  • [IN] struct kcapi_handle *handle : 加密句柄

  • [IN] uint8_t *in : 密文 buffer

  • [IN] uint32_t inlen : 密文长度

  • [IN] uint8_t *iv : 保存 iv 的 buffer

  • [OUT] uint8_t *out : 明文 buffer

  • [OUT] uint32_t outlen : 明文长度

  • [INT] int access : 内核访问类型

    • KCAPI_ACCESS_HEURISTIC - 使用内部启发式方法以实现最快的内核访问

    • KCAPI_ACCESS_VMSPLICE - 通过 vmsplice 访问

    • KCAPI_ACCESS_SENDMSG - 通过sendmsg 访问

【返回值】

  • 解密成功的字节数

使用示例

ssize_t test_aead(const char *name,
                const uint8_t *key, uint32_t keylen,
                const uint8_t *in, size_t inlen,
                const uint8_t *iv, uint32_t assoclen, uint32_t taglen,
                uint8_t *out, size_t outlen)
{
        struct kcapi_handle *handle;
        ssize_t ret = kcapi_aead_init(&handle, name, 0);
        if (ret)
                return ret;
        ret = kcapi_aead_settaglen(handle, taglen);
        if (ret)
                goto out;

        kcapi_aead_setassoclen(handle, assoclen);

        ret = kcapi_aead_setkey(handle, key, keylen);
        if (ret)
                goto out;

        ret = kcapi_aead_encrypt(handle, in, inlen, iv, out, outlen, 0);
out:
        kcapi_aead_destroy(handle);
        return ret;
}