blob: 3e1751a15d12497584dc84983d88d90a8424c284 [file] [log] [blame]
--- a/Makefile.am
+++ b/Makefile.am
@@ -229,6 +229,16 @@ EXTRA_bin_kcapi_dgst_DEPENDENCIES = libt
SCAN_FILES += $(bin_kcapi_dgst_SOURCES)
man_MANS += apps/kcapi-dgst.1
+
+bin_PROGRAMS += bin/kcapi-mtk-dgst
+
+bin_kcapi_mtk_dgst_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/lib/
+bin_kcapi_mtk_dgst_LDFLAGS = $(COMMON_LDFLAGS)
+bin_kcapi_mtk_dgst_LDADD = libkcapi.la
+bin_kcapi_mtk_dgst_SOURCES = apps/kcapi-mtk-dgst.c apps/app-internal.c
+EXTRA_bin_kcapi_dgst_DEPENDENCIES = libtool
+
+SCAN_FILES += $(bin_kcapi_mtk_dgst_SOURCES)
endif
if HAVE_CLANG
--- /dev/null
+++ b/apps/kcapi-mtk-dgst.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2023, MediaTek Inc. All rights reserved.
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <kcapi.h>
+
+#include "app-internal.h"
+
+#define TYPE_SHA 0
+#define TYPE_HMAC 1
+
+static char *name = NULL;
+static unsigned char* key = NULL;
+static unsigned char* message = NULL;
+static uint32_t key_len = 0;
+static uint32_t message_len = 0;
+int type = -1, type_index = -1;
+int empty = 0;
+struct sha {
+ char *name;
+ ssize_t (*fun)(const uint8_t*, size_t,
+ uint8_t*, size_t);
+};
+
+struct hmac {
+ char *name;
+ ssize_t (*fun)(const uint8_t*, uint32_t,
+ const uint8_t*, size_t,
+ uint8_t*, size_t);
+};
+
+struct sha msg_digest[5] = {
+ {
+ .name = "sha1",
+ .fun = kcapi_md_sha1,
+ },
+ {
+ .name = "sha224",
+ .fun = kcapi_md_sha224,
+ },
+ {
+ .name = "sha256",
+ .fun = kcapi_md_sha256,
+ },
+ {
+ .name = "sha384",
+ .fun = kcapi_md_sha384,
+ },
+ {
+ .name = "sha512",
+ .fun = kcapi_md_sha512,
+ },
+};
+
+struct hmac key_msg_digest[5] = {
+ {
+ .name = "hmac-sha1",
+ .fun = kcapi_md_hmac_sha1,
+ },
+ {
+ .name = "hmac-sha224",
+ .fun = kcapi_md_hmac_sha224,
+ },
+ {
+ .name = "hmac-sha256",
+ .fun = kcapi_md_hmac_sha256,
+ },
+ {
+ .name = "hmac-sha384",
+ .fun = kcapi_md_hmac_sha384,
+ },
+ {
+ .name = "hmac-sha512",
+ .fun = kcapi_md_hmac_sha512,
+ },
+};
+
+static unsigned char* hextobin(char* hexstr, uint32_t *ret_len) {
+ size_t len = strlen(hexstr);
+ size_t i = 0;
+ char *pos = hexstr;
+ unsigned char *ret = (unsigned char*) malloc((len + 1) / 2);
+
+ for (i = 0; i < (len + 1) / 2; i++) {
+ if(i == 0 && (len % 2) == 1) {
+ sscanf(pos, "%1hhx", &ret[i]);
+ pos += 1;
+ } else {
+ sscanf(pos, "%2hhx", &ret[i]);
+ pos += 2;
+ }
+ }
+ *ret_len = (len + 1) / 2;
+
+ return ret;
+}
+
+static void uninit() {
+ memset(key, 0, key_len);
+ memset(message, 0, message_len);
+ if(key)
+ free(key);
+ if(message)
+ free(message);
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "\nKernel Crypto API SHA & HMAC\n");
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "\t-k \tKey (hmac required option)\n");
+ fprintf(stderr, "\t-n \tDigest name such as sha1, sha224, sha256 sha512\n");
+ fprintf(stderr, "\t \thmac-sha1 hmac-sha224 hmac-sha256 hmac-sha384 hmac-sha512\n");
+ fprintf(stderr, "\t-m \tmessage(require option))\n");
+ fprintf(stderr, "\t-e \tempty message \n");
+ fprintf(stderr, "\t-l \toutput len(require option))\n");
+ fprintf(stderr, "\t\t\t\tnotation\n");
+ fprintf(stderr, "\t-h --help\t\tThis help information\n");
+
+ uninit();
+ exit(1);
+}
+
+static int check_type(char* name) {
+ int i = 0;
+
+ for(i = 0; i < 5; i++) {
+ if(!strncmp(name, msg_digest[i].name, strlen(name))) {
+ type_index = i;
+ return TYPE_SHA;
+ }
+ }
+
+ for(i = 0; i < 5; i++) {
+ if(!strncmp(name, key_msg_digest[i].name, strlen(name))) {
+ type_index = i;
+ return TYPE_HMAC;
+ }
+ }
+
+ return TYPE_HMAC + 1;
+}
+
+static int parse_opts(int argc, char *argv[], size_t *outlen)
+{
+ int c = 0;
+ size_t len = 0;
+
+ while (1) {
+ int opt_index = 0;
+ static struct option opts[] = {
+ {"key", required_argument, 0, 'k'},
+ {"name", required_argument, 0, 'n'},
+ {"message", required_argument, 0, 'm'},
+ {"len", required_argument, 0, 'l'},
+ {"help", required_argument, 0, 'h'},
+ {"empty", required_argument, 0, 'e'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "k:n:m:l:he", opts, &opt_index);
+ if (-1 == c)
+ break;
+ switch (c) {
+ case 0:
+ switch (opt_index) {
+ case 0:
+ key = hextobin(optarg, &key_len);
+ break;
+ case 1:
+ name = optarg;
+ type = check_type(name);
+ if(type > TYPE_HMAC){
+ usage();
+ return -EINVAL;
+ }
+
+ break;
+ case 2:
+ message = hextobin(optarg, &message_len);
+ break;
+ case 3:
+ len = strtoul(optarg, NULL, 10);
+ if (len == ULONG_MAX) {
+ usage();
+ return -EINVAL;
+ }
+ break;
+ default:
+ usage();
+ }
+ break;
+ case 'k':
+ key = hextobin(optarg, &key_len);
+ break;
+ case 'n':
+ name = optarg;
+ type = check_type(name);
+ if(type > TYPE_HMAC){
+ usage();
+ return -EINVAL;
+ }
+ break;
+ case 'm':
+ message = hextobin(optarg, &message_len);
+ break;
+ case 'l':
+ len = strtoul(optarg, NULL, 10);
+ if (len == ULONG_MAX) {
+ usage();
+ return -EINVAL;
+ }
+ break;
+ case 'e':
+ empty = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if(type == TYPE_HMAC)
+ if(!key)
+ usage();
+ if (!name || !message || !len)
+ usage();
+
+ *outlen = (size_t)len;
+ return 0;
+}
+
+static void print(unsigned char *out, int outlen) {
+ int i = 0;
+
+ for(i = 0; i < outlen; i++)
+ printf("%02x", out[i]);
+ printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+ size_t outlen = 0;
+ ssize_t ret = 0;
+ unsigned char *out = NULL;
+
+ ret = parse_opts(argc, argv, &outlen);
+ if (ret)
+ return (int)ret;
+
+ out = (unsigned char*)malloc(outlen);
+ if (type == TYPE_SHA) {
+ if (empty)
+ ret = msg_digest[type_index].fun(message, 0, out, outlen);
+ else
+ ret = msg_digest[type_index].fun(message, message_len, out, outlen);
+ } else if (type == TYPE_HMAC){
+ if(empty)
+ ret = key_msg_digest[type_index].fun(key, key_len, message, 0,
+ out, outlen);
+ else
+ ret = key_msg_digest[type_index].fun(key, key_len, message, message_len,
+ out, outlen);
+ }
+ if(ret < 0)
+ goto out;
+ print(out, outlen);
+
+out:
+ uninit();
+ if(out)
+ free(out);
+ return (int)ret;
+}