Home | History | Annotate | Download | only in lib
      1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #include <openssl/pem.h>
      7 
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <unistd.h>
     11 
     12 #include "cryptolib.h"
     13 #include "host_common.h"
     14 #include "signature_digest.h"
     15 
     16 
     17 uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) {
     18   const int digest_size = hash_size_map[algorithm];
     19   const int digestinfo_size = digestinfo_size_map[algorithm];
     20   const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
     21   uint8_t* p = malloc(digestinfo_size + digest_size);
     22   Memcpy(p, digestinfo, digestinfo_size);
     23   Memcpy(p + digestinfo_size, digest, digest_size);
     24   return p;
     25 }
     26 
     27 uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
     28                          unsigned int algorithm) {
     29   uint8_t* info_digest  = NULL;
     30   uint8_t* digest = NULL;
     31 
     32   if (algorithm >= kNumAlgorithms) {
     33     VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
     34   } else if ((digest = DigestBuf(buf, len, algorithm))) {
     35     info_digest = PrependDigestInfo(algorithm, digest);
     36   }
     37   free(digest);
     38   return info_digest;
     39 }
     40 
     41 uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
     42                       unsigned int algorithm) {
     43   FILE* key_fp = NULL;
     44   RSA* key = NULL;
     45   uint8_t* signature = NULL;
     46   uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
     47   int signature_digest_len = (hash_size_map[algorithm] +
     48                               digestinfo_size_map[algorithm]);
     49   key_fp  = fopen(key_file, "r");
     50   if (!key_fp) {
     51     VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", key_file));
     52     free(signature_digest);
     53     return NULL;
     54   }
     55   if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
     56     signature = (uint8_t*) malloc(siglen_map[algorithm]);
     57   else
     58     VBDEBUG(("SignatureBuf(): Couldn't read private key from file: %s\n",
     59              key_file));
     60   if (signature) {
     61     if (-1 == RSA_private_encrypt(signature_digest_len,  /* Input length. */
     62                                   signature_digest,  /* Input data. */
     63                                   signature,  /* Output signature. */
     64                                   key,  /* Key to use. */
     65                                   RSA_PKCS1_PADDING))  /* Padding to use. */
     66       VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
     67   }
     68   fclose(key_fp);
     69   if (key)
     70     RSA_free(key);
     71   free(signature_digest);
     72   return signature;
     73 }
     74