summaryrefslogtreecommitdiffstats
path: root/nvme-rpmb.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--nvme-rpmb.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/nvme-rpmb.c b/nvme-rpmb.c
index 7a92934..8f6e6a0 100644
--- a/nvme-rpmb.c
+++ b/nvme-rpmb.c
@@ -1,9 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2020 Micron Techology 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 version
- * 2 as published by the Free Software Foundation.
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -67,6 +69,10 @@ unsigned char *create_hash(const char *algo,
};
/* copy algorith name */
+ if (strlen(algo) > sizeof(provider_sa.salg_name)) {
+ fprintf(stderr, "%s: algorithm name overflow", __func__);
+ return hash;
+ }
memcpy(provider_sa.salg_name, algo, strlen(algo));
/* open netlink socket connection to algorigm provider and bind */
@@ -78,7 +84,7 @@ unsigned char *create_hash(const char *algo,
error = bind(infd, (struct sockaddr *)&provider_sa, sizeof(provider_sa));
if (error < 0) {
perror("bind");
- goto out;
+ goto out_close_infd;
}
/* if algorithm requires key, set it first - empty keys not accepted !*/
@@ -86,27 +92,27 @@ unsigned char *create_hash(const char *algo,
error = setsockopt(infd, SOL_ALG, ALG_SET_KEY, key, keylen);
if (error < 0) {
perror("setsockopt");
- goto out;
+ goto out_close_infd;
}
}
-
+
/* now send data to hash */
outfd = accept(infd, NULL, 0);
if (outfd < 0) {
perror("accept");
- goto out;
+ goto out_close_infd;
}
error = send(outfd, data, datalen, 0);
if (error < 0) {
perror("send");
- goto out;
+ goto out_close_outfd;
}
/* read computed hash */
hash = (unsigned char *)calloc(hash_size, 1);
if (hash == NULL) {
perror("calloc");
- goto out;
+ goto out_close_outfd;
}
error = read(outfd, hash, hash_size);
@@ -115,11 +121,12 @@ unsigned char *create_hash(const char *algo,
free(hash);
hash = NULL;
}
-out:
- if (outfd > 0) close(outfd);
- if (infd > 0) close(infd);
+out_close_outfd:
+ close(outfd);
+out_close_infd:
+ close(infd);
- return hash;
+ return hash;
}
/* Function that computes hmac-sha256 hash of given data and key pair. Returns
@@ -187,9 +194,9 @@ static int read_file(const char *file, unsigned char **data, unsigned int *len)
free(buf);
goto out;
}
- err -= size;
*data = buf;
- *len = size;
+ *len = err;
+ err = 0;
out:
close(fd);
return err;
@@ -321,10 +328,14 @@ static void rpmb_nonce_init(struct rpmb_data_frame_t *req)
static unsigned char *read_rpmb_key(char *keystr, char *keyfile, unsigned int *keysize)
{
unsigned char *keybuf = NULL;
+ int err;
if (keystr == NULL) {
- if (keyfile != NULL)
- read_file(keyfile, &keybuf, keysize);
+ if (keyfile != NULL) {
+ err = read_file(keyfile, &keybuf, keysize);
+ if (err < 0)
+ return NULL;
+ }
} else if ((keybuf = (unsigned char *)malloc(strlen(keystr))) != NULL) {
*keysize = strlen(keystr);
memcpy(keybuf, keystr, *keysize);
@@ -495,10 +506,12 @@ static unsigned int rpmb_read_config_block(int fd, unsigned char **config_buf)
/* initialize request with nonce, no data on input */
req = rpmb_request_init(req_size, RPMB_REQ_AUTH_DCB_READ, 0, 1, 0, 1,
0, 0, 0);
- if ((req == NULL) ||
- (rsp = rpmb_read_request(fd, req, req_size, rsp_size)) == NULL)
+ if (!req)
+ return 0;
+ if ((rsp = rpmb_read_request(fd, req, req_size, rsp_size)) == NULL)
{
- goto out;
+ free(req);
+ return 0;
}
/* copy configuration data to be sent back to caller */
@@ -515,7 +528,6 @@ static unsigned int rpmb_read_config_block(int fd, unsigned char **config_buf)
out:
free(req);
free(rsp);
- free(cfg);
return retval;
}
@@ -544,12 +556,13 @@ static int rpmb_auth_data_read(int fd, unsigned char target,
rsp_size = req_size + xfer * 512;
req = rpmb_request_init(req_size, RPMB_REQ_AUTH_DATA_READ,
target, 1, offset, xfer, 0, 0, 0);
- if (req == NULL) break;
+ if (req == NULL)
+ break;
if ((rsp = rpmb_read_request(fd, req, req_size, rsp_size)) == NULL)
{
fprintf(stderr, "read_request failed\n");
- free(rsp);
- goto out;
+ free(req);
+ break;
}
data_size = rsp->sectors * 512;
@@ -874,7 +887,7 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
} regs;
if ((fd = parse_and_open(argc, argv, desc, opts)) < 0)
- goto out;
+ return fd;
/* before parsing commands, check if controller supports any RPMB targets */
err = nvme_identify_ctrl(fd, &ctrl);
@@ -1031,7 +1044,7 @@ out:
free(msg_buf);
/* close file descriptor */
- if (fd > 0) close(fd);
+ close(fd);
return err;
}