Skip to content

Commit

Permalink
Initial use of new clang-format file
Browse files Browse the repository at this point in the history
This commit is the first use of `make format` which calls the `.clang-format` file on all of the secvarctl specific (not in `external`) source code. All source code should now meet the coding standard we have defined. Since most of the source files have been tweaked in various areas, any type of rebasing before this point will be difficult.

Signed-off-by: Nick Child <nick.child@ibm.com>
  • Loading branch information
nick-child-ibm authored and erichte-ibm committed May 4, 2021
1 parent cba2945 commit 91b68b6
Show file tree
Hide file tree
Showing 15 changed files with 2,409 additions and 1,937 deletions.
1,124 changes: 636 additions & 488 deletions backends/edk2-compat/edk2-svc-generate.c

Large diffs are not rendered by default.

349 changes: 201 additions & 148 deletions backends/edk2-compat/edk2-svc-read.c

Large diffs are not rendered by default.

540 changes: 303 additions & 237 deletions backends/edk2-compat/edk2-svc-validate.c

Large diffs are not rendered by default.

494 changes: 284 additions & 210 deletions backends/edk2-compat/edk2-svc-verify.c

Large diffs are not rendered by default.

177 changes: 93 additions & 84 deletions backends/edk2-compat/edk2-svc-write.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,127 +5,135 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>// for exit
#include <stdlib.h> // for exit
#include <argp.h>
#include "secvarctl.h"
#include "backends/edk2-compat/include/edk2-svc.h"// import last!!
#include "backends/edk2-compat/include/edk2-svc.h" // import last!!


static int updateSecVar(const char *var, const char *authFile, const char *path, int force);
static int updateSecVar(const char *var, const char *authFile, const char *path,
int force);

struct Arguments {
int helpFlag, inpValid;
const char *pathToSecVars, *varName, *inFile;
};
};
static int parse_opt(int key, char *arg, struct argp_state *state);


/*
*called from main()
*handles argument parsing for write command
*@param argc, number of argument
*@param arv, array of params
*@return SUCCESS or err number
*/
int performWriteCommand(int argc, char* argv[])
int performWriteCommand(int argc, char *argv[])
{
int rc;
struct Arguments args = {
.helpFlag = 0, .inpValid = 0,
.pathToSecVars = NULL, .inFile = NULL, .varName = NULL
};
struct Arguments args = { .helpFlag = 0,
.inpValid = 0,
.pathToSecVars = NULL,
.inFile = NULL,
.varName = NULL };
// combine command and subcommand for usage/help messages
argv[0] = "secvarctl write";

struct argp_option options[] =
{
{"verbose", 'v', 0, 0, "print more verbose process information"},
{"force", 'f', 0, 0, "force update, skips validation of file"},
{"path", 'p', "PATH" ,0, "looks for .../<var>/update file in PATH, default is " SECVARPATH},
{"help", '?', 0, 0, "Give this help list", 1},
{"usage", ARGP_OPT_USAGE_KEY, 0, 0, "Give a short usage message", -1 },
{0}
struct argp_option options[] = {
{ "verbose", 'v', 0, 0,
"print more verbose process information" },
{ "force", 'f', 0, 0,
"force update, skips validation of file" },
{ "path", 'p', "PATH", 0,
"looks for .../<var>/update file in PATH, default is " SECVARPATH },
{ "help", '?', 0, 0, "Give this help list", 1 },
{ "usage", ARGP_OPT_USAGE_KEY, 0, 0,
"Give a short usage message", -1 },
{ 0 }
};

struct argp argp = {
options, parse_opt, "<VARIABLE> <AUTH_FILE>",
options, parse_opt, "<VARIABLE> <AUTH_FILE>",
"This command updates a given secure variable with a new key contained in an auth file"
" It is recommended that 'secvarctl verify' is tried on the update file before submitting."
" This will ensure that the submission will be successful upon reboot."
"\vvalues for <VARIABLE> = type one of {'PK','KEK','db','dbx'}\n"
"<AUTH_FILE> must be a properly generated authenticated variable file"
};

rc = argp_parse( &argp, argc, argv, ARGP_NO_EXIT | ARGP_IN_ORDER | ARGP_NO_HELP, 0, &args);
rc = argp_parse(&argp, argc, argv,
ARGP_NO_EXIT | ARGP_IN_ORDER | ARGP_NO_HELP, 0, &args);
if (rc || args.helpFlag)
goto out;


rc = updateSecVar(args.varName, args.inFile, args.pathToSecVars, args.inpValid);
rc = updateSecVar(args.varName, args.inFile, args.pathToSecVars,
args.inpValid);

out:
if (!args.helpFlag)
if (!args.helpFlag)
printf("RESULT: %s\n", rc ? "FAILURE" : "SUCCESS");

return rc;
return rc;
}


/**
*@param key , every option that is parsed has a value to identify it
*@param arg, if key is an option than arg will hold its value ex: -<key> <arg>
*@param state, argp_state struct that contains useful information about the current parsing state
*@return success or errno
*/
static int parse_opt(int key, char *arg, struct argp_state *state)
static int parse_opt(int key, char *arg, struct argp_state *state)
{
struct Arguments *args = state->input;
int rc = SUCCESS;

switch (key) {
case '?':
args->helpFlag = 1;
argp_state_help(state, stdout, ARGP_HELP_STD_HELP);
break;
case ARGP_OPT_USAGE_KEY:
args->helpFlag = 1;
argp_state_help(state, stdout, ARGP_HELP_USAGE);
break;
case 'p':
args->pathToSecVars = arg;
break;
case 'f':
args->inpValid = 1;
case '?':
args->helpFlag = 1;
argp_state_help(state, stdout, ARGP_HELP_STD_HELP);
break;
case ARGP_OPT_USAGE_KEY:
args->helpFlag = 1;
argp_state_help(state, stdout, ARGP_HELP_USAGE);
break;
case 'p':
args->pathToSecVars = arg;
break;
case 'f':
args->inpValid = 1;
break;
case 'v':
verbose = PR_DEBUG;
break;
case ARGP_KEY_ARG:
if (args->varName == NULL)
args->varName = arg;
else if (args->inFile == NULL)
args->inFile = arg;
break;
case ARGP_KEY_SUCCESS:
// check that all essential args are given and valid
if (args->helpFlag)
break;
case 'v':
verbose = PR_DEBUG;
break;
case ARGP_KEY_ARG:
if (args->varName == NULL)
args->varName = arg;
else if (args->inFile == NULL)
args->inFile = arg;
break;
case ARGP_KEY_SUCCESS:
// check that all essential args are given and valid
if (args->helpFlag)
break;
if(!args->varName)
prlog(PR_ERR, "ERROR: missing variable, see usage...\n");
else if (!args->inFile)
prlog(PR_ERR, "ERROR: missing input file, see usage...\n");
else if (isVariable(args->varName))
prlog(PR_ERR, "ERROR: Unrecognized variable name %s, see usage...\n", args->varName);
else if (strcmp(args->varName, "TS") == 0)
prlog(PR_ERR, "ERROR: Cannot update TimeStamp (TS) variable, see usage...\n");
else
break;
argp_usage(state);
rc = args->inFile ? INVALID_VAR_NAME : ARG_PARSE_FAIL;
if (!args->varName)
prlog(PR_ERR,
"ERROR: missing variable, see usage...\n");
else if (!args->inFile)
prlog(PR_ERR,
"ERROR: missing input file, see usage...\n");
else if (isVariable(args->varName))
prlog(PR_ERR,
"ERROR: Unrecognized variable name %s, see usage...\n",
args->varName);
else if (strcmp(args->varName, "TS") == 0)
prlog(PR_ERR,
"ERROR: Cannot update TimeStamp (TS) variable, see usage...\n");
else
break;
argp_usage(state);
rc = args->inFile ? INVALID_VAR_NAME : ARG_PARSE_FAIL;
break;
}

if (rc)
if (rc)
prlog(PR_ERR, "Failed during argument parsing\n");

return rc;
Expand All @@ -136,10 +144,10 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
*@param var variable name
*@return SUCCESS or error code
*/
int isVariable(const char * var)
int isVariable(const char *var)
{
for (int i = 0; i < ARRAY_SIZE(variables); i++) {
if (strcmp(var,variables[i]) == 0)
if (strcmp(var, variables[i]) == 0)
return SUCCESS;
}

Expand All @@ -154,31 +162,34 @@ int isVariable(const char * var)
*@param force 1 for no validation of auth, 0 for validate
*@return error if variable given is unknown, or issue validating or writing
*/
static int updateSecVar(const char *varName, const char *authFile, const char *path, int force)
{
static int updateSecVar(const char *varName, const char *authFile,
const char *path, int force)
{
int rc;
unsigned char *buff = NULL;
size_t size;

if (!path) {
path = SECVARPATH;
}
}

// get data to write, if force flag then validate the data is an auth file
buff = (unsigned char *)getDataFromFile(authFile, &size);
buff = (unsigned char *)getDataFromFile(authFile, &size);
// if we are validating and validating fails, quit
if (!force) {
if (!force) {
rc = validateAuth(buff, size, varName);
if (rc) {
prlog(PR_ERR, "ERROR: validating update file (Signed Auth) failed, not updating\n");
prlog(PR_ERR,
"ERROR: validating update file (Signed Auth) failed, not updating\n");
free(buff);
return rc;
}
}
rc = updateVar(path, varName, buff, size);

if (rc)
prlog(PR_ERR, "ERROR: issue writing to file: %s\n", strerror(errno));
if (rc)
prlog(PR_ERR, "ERROR: issue writing to file: %s\n",
strerror(errno));
free(buff);

return rc;
Expand All @@ -192,14 +203,15 @@ static int updateSecVar(const char *varName, const char *authFile, const char *p
*@param size , size of buff
*@return whatever returned by writeData, SUCCESS or errno
*/
int updateVar(const char *path, const char *var, const unsigned char *buff, size_t size)
{
int commandLength, rc;
int updateVar(const char *path, const char *var, const unsigned char *buff,
size_t size)
{
int commandLength, rc;
char *fullPathWithCommand = NULL;

commandLength = strlen(path) + strlen(var) + strlen("/update ");
fullPathWithCommand = malloc(commandLength);
if (!fullPathWithCommand) {
if (!fullPathWithCommand) {
prlog(PR_ERR, "ERROR: failed to allocate memory\n");
return ALLOC_FAIL;
}
Expand All @@ -212,7 +224,4 @@ int updateVar(const char *path, const char *var, const unsigned char *buff, size
free(fullPathWithCommand);

return rc;

}


68 changes: 44 additions & 24 deletions backends/edk2-compat/include/edk2-svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,78 @@
#include "crypto/crypto.h"
#include "external/skiboot/include/edk2.h" // include last or else problems from pragma pack(1)


// all argp options must have a single character option
// all argp options must have a single character option
// so we set --usage to have a single character option that is out of range
#define ARGP_OPT_USAGE_KEY 0x100
#define CERT_BUFFER_SIZE 2048
#define CERT_BUFFER_SIZE 2048

#ifndef SECVARPATH
#define SECVARPATH "/sys/firmware/secvar/vars/"
#endif

#define variables (char* []){ "PK", "KEK", "db", "dbx", "TS" }
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#define uuid_equals(a,b) (!memcmp(a, b, UUID_SIZE))
#define variables \
(char *[]) \
{ \
"PK", "KEK", "db", "dbx", "TS" \
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define uuid_equals(a, b) (!memcmp(a, b, UUID_SIZE))

// array holding different hash function information
static const struct hash_funct {
char name[8];
size_t size;
int crypto_md_funct;
uuid_t const* guid;
char name[8];
size_t size;
int crypto_md_funct;
uuid_t const *guid;
} hash_functions[] = {
{ .name = "SHA1", .size = 20 , .crypto_md_funct = CRYPTO_MD_SHA1, .guid = &EFI_CERT_SHA1_GUID },
{ .name = "SHA224", .size = 28 , .crypto_md_funct = CRYPTO_MD_SHA224, .guid = &EFI_CERT_SHA224_GUID },
{ .name = "SHA256", .size = 32, .crypto_md_funct = CRYPTO_MD_SHA256, .guid = &EFI_CERT_SHA256_GUID },
{ .name = "SHA384", .size = 48, .crypto_md_funct = CRYPTO_MD_SHA384, .guid = &EFI_CERT_SHA384_GUID },
{ .name = "SHA512", .size = 64, .crypto_md_funct = CRYPTO_MD_SHA512, .guid = &EFI_CERT_SHA512_GUID },
{ .name = "SHA1",
.size = 20,
.crypto_md_funct = CRYPTO_MD_SHA1,
.guid = &EFI_CERT_SHA1_GUID },
{ .name = "SHA224",
.size = 28,
.crypto_md_funct = CRYPTO_MD_SHA224,
.guid = &EFI_CERT_SHA224_GUID },
{ .name = "SHA256",
.size = 32,
.crypto_md_funct = CRYPTO_MD_SHA256,
.guid = &EFI_CERT_SHA256_GUID },
{ .name = "SHA384",
.size = 48,
.crypto_md_funct = CRYPTO_MD_SHA384,
.guid = &EFI_CERT_SHA384_GUID },
{ .name = "SHA512",
.size = 64,
.crypto_md_funct = CRYPTO_MD_SHA512,
.guid = &EFI_CERT_SHA512_GUID },
};

int performReadCommand(int argc, char *argv[]);
int performVerificationCommand(int argc, char *argv[]);
int performVerificationCommand(int argc, char *argv[]);
int performWriteCommand(int argc, char *argv[]);
int performValidation(int argc, char* argv[]);
int performGenerateCommand(int argc, char* argv[]);
int performValidation(int argc, char *argv[]);
int performGenerateCommand(int argc, char *argv[]);

int printCertInfo(crypto_x509 *x509);
void printESLInfo(EFI_SIGNATURE_LIST *sigList);
void printTimestamp(struct efi_time t);
void printGuidSig(const void *sig);

EFI_SIGNATURE_LIST* get_esl_signature_list(const char *buf, size_t buflen);
ssize_t get_esl_cert( const char *c,EFI_SIGNATURE_LIST *list ,char **cert);
EFI_SIGNATURE_LIST *get_esl_signature_list(const char *buf, size_t buflen);
ssize_t get_esl_cert(const char *c, EFI_SIGNATURE_LIST *list, char **cert);
size_t get_pkcs7_len(const struct efi_variable_authentication_2 *auth);
int parseX509(crypto_x509 **x509, const unsigned char *certBuf, size_t buflen);
const char* getSigType(const uuid_t);
const char *getSigType(const uuid_t);

int getSecVar(struct secvar **var, const char* name, const char *fullPath);
int updateVar(const char* path, const char* var, const unsigned char* buff, size_t size);
int getSecVar(struct secvar **var, const char *name, const char *fullPath);
int updateVar(const char *path, const char *var, const unsigned char *buff,
size_t size);
int isVariable(const char *var);

int validateAuth(const unsigned char *authBuf, size_t buflen, const char *key);
int validateESL(const unsigned char *eslBuf, size_t buflen, const char *key);
int validateCert(const unsigned char *authBuf, size_t buflen, const char *varName);
int validateCert(const unsigned char *authBuf, size_t buflen,
const char *varName);
int validatePKCS7(const unsigned char *cert_data, size_t len);
int validateTS(const unsigned char *data, size_t size);
int validateTime(struct efi_time *time);
Expand Down
Loading

0 comments on commit 91b68b6

Please sign in to comment.