1*5acaca2fSWilliam A. Kennington III /* 2*5acaca2fSWilliam A. Kennington III * Copyright 2021 Google LLC 3*5acaca2fSWilliam A. Kennington III * 4*5acaca2fSWilliam A. Kennington III * Licensed under the Apache License, Version 2.0 (the "License"); 5*5acaca2fSWilliam A. Kennington III * you may not use this file except in compliance with the License. 6*5acaca2fSWilliam A. Kennington III * You may obtain a copy of the License at 7*5acaca2fSWilliam A. Kennington III * 8*5acaca2fSWilliam A. Kennington III * http://www.apache.org/licenses/LICENSE-2.0 9*5acaca2fSWilliam A. Kennington III * 10*5acaca2fSWilliam A. Kennington III * Unless required by applicable law or agreed to in writing, software 11*5acaca2fSWilliam A. Kennington III * distributed under the License is distributed on an "AS IS" BASIS, 12*5acaca2fSWilliam A. Kennington III * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*5acaca2fSWilliam A. Kennington III * See the License for the specific language governing permissions and 14*5acaca2fSWilliam A. Kennington III * limitations under the License. 15*5acaca2fSWilliam A. Kennington III */ 16*5acaca2fSWilliam A. Kennington III #include <libcr51sign/libcr51sign_support.h> 17*5acaca2fSWilliam A. Kennington III #include <openssl/evp.h> 18*5acaca2fSWilliam A. Kennington III #include <openssl/pem.h> 19*5acaca2fSWilliam A. Kennington III #include <openssl/rsa.h> 20*5acaca2fSWilliam A. Kennington III #include <stdio.h> 21*5acaca2fSWilliam A. Kennington III #include <string.h> 22*5acaca2fSWilliam A. Kennington III 23*5acaca2fSWilliam A. Kennington III #ifdef __cplusplus 24*5acaca2fSWilliam A. Kennington III extern "C" 25*5acaca2fSWilliam A. Kennington III { 26*5acaca2fSWilliam A. Kennington III #endif 27*5acaca2fSWilliam A. Kennington III 28*5acaca2fSWilliam A. Kennington III // @func hash_init get ready to compute a hash 29*5acaca2fSWilliam A. Kennington III // 30*5acaca2fSWilliam A. Kennington III // @param[in] ctx - context struct 31*5acaca2fSWilliam A. Kennington III // @param[in] hash_type - type of hash function to use 32*5acaca2fSWilliam A. Kennington III // 33*5acaca2fSWilliam A. Kennington III // @return nonzero on error, zero on success 34*5acaca2fSWilliam A. Kennington III 35*5acaca2fSWilliam A. Kennington III int hash_init(const void* ctx, enum hash_type type) 36*5acaca2fSWilliam A. Kennington III { 37*5acaca2fSWilliam A. Kennington III struct libcr51sign_ctx* context = (struct libcr51sign_ctx*)ctx; 38*5acaca2fSWilliam A. Kennington III struct hash_ctx* hash_context = (struct hash_ctx*)context->priv; 39*5acaca2fSWilliam A. Kennington III hash_context->hash_type = type; 40*5acaca2fSWilliam A. Kennington III if (type == HASH_SHA2_256) // SHA256_Init returns 1 41*5acaca2fSWilliam A. Kennington III SHA256_Init(&hash_context->sha256_ctx); 42*5acaca2fSWilliam A. Kennington III else if (type == HASH_SHA2_512) 43*5acaca2fSWilliam A. Kennington III SHA512_Init(&hash_context->sha512_ctx); 44*5acaca2fSWilliam A. Kennington III else 45*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 46*5acaca2fSWilliam A. Kennington III 47*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_SUCCESS; 48*5acaca2fSWilliam A. Kennington III } 49*5acaca2fSWilliam A. Kennington III 50*5acaca2fSWilliam A. Kennington III // @func hash_update add data to the hash 51*5acaca2fSWilliam A. Kennington III // 52*5acaca2fSWilliam A. Kennington III // @param[in] ctx - context struct 53*5acaca2fSWilliam A. Kennington III // @param[in] buf - data to add to hash 54*5acaca2fSWilliam A. Kennington III // @param[in] count - number of bytes of data to add 55*5acaca2fSWilliam A. Kennington III // 56*5acaca2fSWilliam A. Kennington III // @return nonzero on error, zero on success 57*5acaca2fSWilliam A. Kennington III 58*5acaca2fSWilliam A. Kennington III int hash_update(void* ctx, const uint8_t* data, size_t size) 59*5acaca2fSWilliam A. Kennington III { 60*5acaca2fSWilliam A. Kennington III if (size == 0) 61*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_SUCCESS; 62*5acaca2fSWilliam A. Kennington III struct libcr51sign_ctx* context = (struct libcr51sign_ctx*)ctx; 63*5acaca2fSWilliam A. Kennington III struct hash_ctx* hash_context = (struct hash_ctx*)context->priv; 64*5acaca2fSWilliam A. Kennington III 65*5acaca2fSWilliam A. Kennington III if (hash_context->hash_type == HASH_SHA2_256) // SHA256_Update returns 1 66*5acaca2fSWilliam A. Kennington III SHA256_Update(&hash_context->sha256_ctx, data, size); 67*5acaca2fSWilliam A. Kennington III else if (hash_context->hash_type == HASH_SHA2_512) 68*5acaca2fSWilliam A. Kennington III SHA512_Update(&hash_context->sha512_ctx, data, size); 69*5acaca2fSWilliam A. Kennington III else 70*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 71*5acaca2fSWilliam A. Kennington III 72*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_SUCCESS; 73*5acaca2fSWilliam A. Kennington III } 74*5acaca2fSWilliam A. Kennington III 75*5acaca2fSWilliam A. Kennington III // @func hash_final finish hash calculation 76*5acaca2fSWilliam A. Kennington III // 77*5acaca2fSWilliam A. Kennington III // @param[in] ctx - context struct 78*5acaca2fSWilliam A. Kennington III // @param[out] hash - buffer to write hash to (guaranteed to be big enough) 79*5acaca2fSWilliam A. Kennington III // 80*5acaca2fSWilliam A. Kennington III // @return nonzero on error, zero on success 81*5acaca2fSWilliam A. Kennington III 82*5acaca2fSWilliam A. Kennington III int hash_final(void* ctx, uint8_t* hash) 83*5acaca2fSWilliam A. Kennington III { 84*5acaca2fSWilliam A. Kennington III int rv; 85*5acaca2fSWilliam A. Kennington III struct libcr51sign_ctx* context = (struct libcr51sign_ctx*)ctx; 86*5acaca2fSWilliam A. Kennington III struct hash_ctx* hash_context = (struct hash_ctx*)context->priv; 87*5acaca2fSWilliam A. Kennington III 88*5acaca2fSWilliam A. Kennington III if (hash_context->hash_type == HASH_SHA2_256) 89*5acaca2fSWilliam A. Kennington III rv = SHA256_Final(hash, &hash_context->sha256_ctx); 90*5acaca2fSWilliam A. Kennington III else if (hash_context->hash_type == HASH_SHA2_512) 91*5acaca2fSWilliam A. Kennington III rv = SHA512_Final(hash, &hash_context->sha512_ctx); 92*5acaca2fSWilliam A. Kennington III else 93*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 94*5acaca2fSWilliam A. Kennington III 95*5acaca2fSWilliam A. Kennington III if (rv) 96*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_SUCCESS; 97*5acaca2fSWilliam A. Kennington III else 98*5acaca2fSWilliam A. Kennington III return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 99*5acaca2fSWilliam A. Kennington III } 100*5acaca2fSWilliam A. Kennington III 101*5acaca2fSWilliam A. Kennington III // @func verify check that the signature is valid for given hashed data 102*5acaca2fSWilliam A. Kennington III // 103*5acaca2fSWilliam A. Kennington III // @param[in] ctx - context struct 104*5acaca2fSWilliam A. Kennington III // @param[in] scheme - type of signature, hash, etc. 105*5acaca2fSWilliam A. Kennington III // @param[in] sig - signature blob 106*5acaca2fSWilliam A. Kennington III // @param[in] sig_len - length of signature in bytes 107*5acaca2fSWilliam A. Kennington III // @param[in] data - pre-hashed data to verify 108*5acaca2fSWilliam A. Kennington III // @param[in] data_len - length of hashed data in bytes 109*5acaca2fSWilliam A. Kennington III // 110*5acaca2fSWilliam A. Kennington III // verify_signature expects RSA public key file path in ctx->key_ring 111*5acaca2fSWilliam A. Kennington III // @return nonzero on error, zero on success 112*5acaca2fSWilliam A. Kennington III 113*5acaca2fSWilliam A. Kennington III int verify_signature(const void* ctx, enum signature_scheme sig_scheme, 114*5acaca2fSWilliam A. Kennington III const uint8_t* sig, size_t sig_len, 115*5acaca2fSWilliam A. Kennington III const uint8_t* data, size_t data_len) 116*5acaca2fSWilliam A. Kennington III { 117*5acaca2fSWilliam A. Kennington III // By default returns error. 118*5acaca2fSWilliam A. Kennington III int rv = LIBCR51SIGN_ERROR_INVALID_ARGUMENT; 119*5acaca2fSWilliam A. Kennington III 120*5acaca2fSWilliam A. Kennington III printf("\n sig_len %zu sig: ", sig_len); 121*5acaca2fSWilliam A. Kennington III for (int i = 0; i < sig_len; i++) 122*5acaca2fSWilliam A. Kennington III { 123*5acaca2fSWilliam A. Kennington III printf("%x", sig[i]); 124*5acaca2fSWilliam A. Kennington III } 125*5acaca2fSWilliam A. Kennington III 126*5acaca2fSWilliam A. Kennington III struct libcr51sign_ctx* lctx = (struct libcr51sign_ctx*)ctx; 127*5acaca2fSWilliam A. Kennington III FILE* fp = fopen(lctx->keyring, "r"); 128*5acaca2fSWilliam A. Kennington III RSA *rsa = NULL, *pub_rsa = NULL; 129*5acaca2fSWilliam A. Kennington III EVP_PKEY* pkey = NULL; 130*5acaca2fSWilliam A. Kennington III BIO* bio = BIO_new(BIO_s_mem()); 131*5acaca2fSWilliam A. Kennington III if (!fp) 132*5acaca2fSWilliam A. Kennington III { 133*5acaca2fSWilliam A. Kennington III printf("\n fopen failed: "); 134*5acaca2fSWilliam A. Kennington III goto clean_up; 135*5acaca2fSWilliam A. Kennington III } 136*5acaca2fSWilliam A. Kennington III 137*5acaca2fSWilliam A. Kennington III pkey = PEM_read_PUBKEY(fp, 0, 0, 0); 138*5acaca2fSWilliam A. Kennington III if (!pkey) 139*5acaca2fSWilliam A. Kennington III { 140*5acaca2fSWilliam A. Kennington III printf("\n Read public key failed: "); 141*5acaca2fSWilliam A. Kennington III goto clean_up; 142*5acaca2fSWilliam A. Kennington III } 143*5acaca2fSWilliam A. Kennington III 144*5acaca2fSWilliam A. Kennington III rsa = EVP_PKEY_get1_RSA(pkey); 145*5acaca2fSWilliam A. Kennington III if (!rsa) 146*5acaca2fSWilliam A. Kennington III { 147*5acaca2fSWilliam A. Kennington III goto clean_up; 148*5acaca2fSWilliam A. Kennington III } 149*5acaca2fSWilliam A. Kennington III pub_rsa = RSAPublicKey_dup(rsa); 150*5acaca2fSWilliam A. Kennington III if (!RSA_print(bio, pub_rsa, 2)) 151*5acaca2fSWilliam A. Kennington III { 152*5acaca2fSWilliam A. Kennington III printf("\n RSA print failed "); 153*5acaca2fSWilliam A. Kennington III } 154*5acaca2fSWilliam A. Kennington III if (!pub_rsa) 155*5acaca2fSWilliam A. Kennington III { 156*5acaca2fSWilliam A. Kennington III printf("\n no pub rsa: "); 157*5acaca2fSWilliam A. Kennington III goto clean_up; 158*5acaca2fSWilliam A. Kennington III } 159*5acaca2fSWilliam A. Kennington III printf("\n public rsa \n"); 160*5acaca2fSWilliam A. Kennington III char buffer[1024]; 161*5acaca2fSWilliam A. Kennington III while (BIO_read(bio, buffer, sizeof(buffer) - 1) > 0) 162*5acaca2fSWilliam A. Kennington III { 163*5acaca2fSWilliam A. Kennington III printf(" %s", buffer); 164*5acaca2fSWilliam A. Kennington III } 165*5acaca2fSWilliam A. Kennington III enum hash_type hash_type; 166*5acaca2fSWilliam A. Kennington III rv = get_hash_type_from_signature(sig_scheme, &hash_type); 167*5acaca2fSWilliam A. Kennington III if (rv != LIBCR51SIGN_SUCCESS) 168*5acaca2fSWilliam A. Kennington III { 169*5acaca2fSWilliam A. Kennington III printf("\n Invalid hash_type! \n"); 170*5acaca2fSWilliam A. Kennington III goto clean_up; 171*5acaca2fSWilliam A. Kennington III } 172*5acaca2fSWilliam A. Kennington III int hash_nid = -1; 173*5acaca2fSWilliam A. Kennington III if (hash_type == HASH_SHA2_256) 174*5acaca2fSWilliam A. Kennington III { 175*5acaca2fSWilliam A. Kennington III hash_nid = NID_sha256; 176*5acaca2fSWilliam A. Kennington III } 177*5acaca2fSWilliam A. Kennington III else if (hash_type == HASH_SHA2_512) 178*5acaca2fSWilliam A. Kennington III { 179*5acaca2fSWilliam A. Kennington III hash_nid = NID_sha512; 180*5acaca2fSWilliam A. Kennington III } 181*5acaca2fSWilliam A. Kennington III else 182*5acaca2fSWilliam A. Kennington III { 183*5acaca2fSWilliam A. Kennington III rv = LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 184*5acaca2fSWilliam A. Kennington III goto clean_up; 185*5acaca2fSWilliam A. Kennington III } 186*5acaca2fSWilliam A. Kennington III 187*5acaca2fSWilliam A. Kennington III int ret = RSA_verify(hash_nid, data, data_len, sig, sig_len, pub_rsa); 188*5acaca2fSWilliam A. Kennington III // OpenSSL RSA_verify returns 1 on success and 0 on failure 189*5acaca2fSWilliam A. Kennington III if (!ret) 190*5acaca2fSWilliam A. Kennington III { 191*5acaca2fSWilliam A. Kennington III printf("\n OPENSSL_ERROR: %s \n", 192*5acaca2fSWilliam A. Kennington III ERR_error_string(ERR_get_error(), NULL)); 193*5acaca2fSWilliam A. Kennington III rv = LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 194*5acaca2fSWilliam A. Kennington III goto clean_up; 195*5acaca2fSWilliam A. Kennington III } 196*5acaca2fSWilliam A. Kennington III rv = LIBCR51SIGN_SUCCESS; 197*5acaca2fSWilliam A. Kennington III printf("\n sig: "); 198*5acaca2fSWilliam A. Kennington III for (int i = 0; i < sig_len; i++) 199*5acaca2fSWilliam A. Kennington III { 200*5acaca2fSWilliam A. Kennington III printf("%x", sig[i]); 201*5acaca2fSWilliam A. Kennington III } 202*5acaca2fSWilliam A. Kennington III 203*5acaca2fSWilliam A. Kennington III printf("\n data: "); 204*5acaca2fSWilliam A. Kennington III for (int i = 0; i < data_len; i++) 205*5acaca2fSWilliam A. Kennington III { 206*5acaca2fSWilliam A. Kennington III printf("%x", data[i]); 207*5acaca2fSWilliam A. Kennington III } 208*5acaca2fSWilliam A. Kennington III const unsigned rsa_size = RSA_size(pub_rsa); 209*5acaca2fSWilliam A. Kennington III printf("\n rsa size %d sig_len %d", rsa_size, (uint32_t)sig_len); 210*5acaca2fSWilliam A. Kennington III 211*5acaca2fSWilliam A. Kennington III clean_up: 212*5acaca2fSWilliam A. Kennington III if (fp) 213*5acaca2fSWilliam A. Kennington III { 214*5acaca2fSWilliam A. Kennington III fclose(fp); 215*5acaca2fSWilliam A. Kennington III } 216*5acaca2fSWilliam A. Kennington III EVP_PKEY_free(pkey); 217*5acaca2fSWilliam A. Kennington III RSA_free(rsa); 218*5acaca2fSWilliam A. Kennington III RSA_free(pub_rsa); 219*5acaca2fSWilliam A. Kennington III BIO_free(bio); 220*5acaca2fSWilliam A. Kennington III return rv; 221*5acaca2fSWilliam A. Kennington III } 222*5acaca2fSWilliam A. Kennington III 223*5acaca2fSWilliam A. Kennington III #ifdef __cplusplus 224*5acaca2fSWilliam A. Kennington III } // extern "C" 225*5acaca2fSWilliam A. Kennington III #endif 226