blob: 21f1f8f812f396412d1a9b8cc32a116bd19e6a0d [file] [log] [blame]
#include "rsa_params.h"
#include <stdio.h>
#include <stdlib.h>
static const char header_name[] = "rsa_public_key.h";
static const char header_prefix[] =
"/*\n"
" * Automatically generated from generate_public_key_code.c\n"
" *\n"
" * DO NOT EDIT.\n"
" */\n"
"\n"
"#ifndef _RSA_PUBLIC_KEY_H\n"
"#define _RSA_PUBLIC_KEY_H\n"
"\n"
"#include <common.h>\n"
"\n";
static const char header_suffix[] = "\n#endif\n";
static const int col_width = 6;
/*
* Formats and outputs a uint32_t array as C code to a file.
*
* Returns 0 on success, non-zero if unable to write any of the parts.
*/
static int _output_int32_t_arr(FILE *fp, char *arr_name, uint32_t *arr,
unsigned int len) {
int i;
if (fprintf(fp, "uint32_t %s[] = {\n\t", arr_name) <= 0) {
return 1;
}
/* Print all but the last element. */
for (i = 0; i < len - 1; ++i) {
if ((i % col_width) == 0 && i > 0) {
if (fprintf(fp, ",\n\t") != 3) return 1;
}
if ((i % col_width) > 0) {
if (fprintf(fp, ", ") != 2) return 1;
}
if (fprintf(fp, "0x%.8x", arr[i]) != 10) return 1;
}
/* Print the last element */
if ((i % col_width) == 0 && i > 0) {
if (fprintf(fp, ",\n\t") != 3) return 1;
if (fprintf(fp, "0x%.8x", arr[i]) != 10) return 1;
} else {
if (fprintf(fp, ", 0x%.8x", arr[i]) != 12) return 1;
}
if (fprintf(fp, "\n};\n") != 4) return 1;
return 0;
}
static int _generate_verify_data_code(uint32_t *modulus, uint32_t *rr,
uint32_t n0inv, unsigned int len) {
int num_elements, i, num_chars;
FILE *header_file;
int ret = 0, len_in_words;
header_file = fopen(header_name, "w");
if (!header_file) {
fprintf(stderr, "Unable to open file %s\n", header_name);
return 1;
}
if (fprintf(header_file, header_prefix) != (sizeof(header_prefix) - 1)) {
fprintf(stderr, "Unable to write prefix to header file.\n");
ret = 1;
goto end;
}
/* The verification code requires the key length in 32-bit words. */
len_in_words = len / 32;
if (fprintf(header_file, "#define KEY_LEN_WORDS %u\n\n", len_in_words) <= 0) {
fprintf(stderr, "Unable to write len to header file.\n");
ret = 1;
goto end;
}
if (fprintf(header_file, "uint32_t n0inv = %uu;\n", n0inv) <= 0) {
fprintf(stderr, "Unable to write n0inv to header file.\n");
ret = 1;
goto end;
}
// Convert len from bits to multiple of uint32_t.
num_elements = len / (8 * sizeof(uint32_t));
if (_output_int32_t_arr(header_file, "modulus", modulus, num_elements)) {
fprintf(stderr, "Unable to write modulus to header file.\n");
ret = 1;
goto end;
}
if (_output_int32_t_arr(header_file, "rr", rr, num_elements)) {
fprintf(stderr, "Unable to write rr to header file.\n");
ret = 1;
goto end;
}
if (fprintf(header_file, header_suffix) != (sizeof(header_suffix) - 1)) {
fprintf(stderr, "Unable to write suffix to header file.\n");
ret = 1;
goto end;
}
end:
close(header_file);
return ret;
}
int main(int argc, char *argv[]) {
uint32_t *modulus, *r_squared;
uint32_t n0inv;
int len, ret;
if (argc < 2) {
printf("Usage: %s pub_key_file\n", argv[0]);
printf(" The resultant code is written to rsa_public_key.h\n\n");
return 1;
}
modulus = NULL;
r_squared = NULL;
ret = rsa_get_verify_data(argv[1], &modulus, &r_squared, &n0inv, &len);
if (ret) {
fprintf(stderr, "Error in getting parameters\n");
goto end;
}
ret = _generate_verify_data_code(modulus, r_squared, n0inv, len);
if (ret) {
fprintf(stderr, "Error generating verify data code\n");
goto end;
}
end:
if (modulus != NULL)
free(modulus);
if (r_squared != NULL)
free(r_squared);
return ret;
}