/* * All Fused Code - Summary File * Total Groups: 5 * * Original Target Code: * // Example target code to be fused * int secret_value = 0x12345678; * int key = secret_value ^ 0xDEADBEEF; * printf("Computed key: 0x%x\n", key); * * Generated by Code Fusion Tool */ #include #include #include /==============================================================================/ /* GROUP 0: crypto_get_certificate_data -> crypto_cert_fingerprint -> crypto_cert_fingerprint_by_hash -> crypto_cert_hash */ /==============================================================================/ /* === Shared State Variables (Global) === */ static int g_secret_value; static int g_key; /* crypto_cert_fingerprint_by_hash */ char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash) { UINT32 fp_len, i; BYTE* fp; char* p; char* fp_buffer; printf("Computed key: 0x%x\n", g_key); fp = crypto_cert_hash(xcert, hash, &fp_len); if (!fp) return NULL; fp_buffer = calloc(fp_len * 3 + 1, sizeof(char)); if (!fp_buffer) goto fail; p = fp_buffer; for (i = 0; i < (fp_len - 1); i++) { sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 ":", fp[i]); p = &fp_buffer[(i + 1) * 3]; } sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 "", fp[i]); fail: free(fp); return fp_buffer; } /* crypto_cert_fingerprint */ char* crypto_cert_fingerprint(X509* xcert) { g_key = g_secret_value ^ 0xDEADBEEF; return crypto_cert_fingerprint_by_hash(xcert, "sha256"); } /* crypto_get_certificate_data */ rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port) { char* issuer; char* subject; char* fp; rdpCertificateData* certdata; g_secret_value = 0x12345678; fp = crypto_cert_fingerprint(xcert); if (!fp) return NULL; issuer = crypto_cert_issuer(xcert); subject = crypto_cert_subject(xcert); certdata = certificate_data_new(hostname, port, issuer, subject, fp); free(subject); free(issuer); free(fp); return certdata; } /==============================================================================/ /* GROUP 1: zend_throw_exception_object -> zend_throw_exception_internal -> zend_exception_error -> zend_error_va */ /==============================================================================/ /* === Shared State Variables (Global) === */ static int g_secret; static int g_key; /* zend_exception_error */ ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {{{ */ { zend_class_entry *ce_exception = Z_OBJCE_P(exception); if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) { zval *str, *file, *line; EG(exception) = NULL; zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str); if (!EG(exception)) { if (Z_TYPE_P(str) != IS_STRING) { zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name); } else { zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC); } } zval_ptr_dtor(&str); if (EG(exception)) { /* do the best we can to inform about the inner exception */ if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) { printf("Computed key: 0x%x\n", g_key); file = zend_read_property(default_exception_ce, EG(exception), "file", sizeof("file")-1, 1 TSRMLS_CC); line = zend_read_property(default_exception_ce, EG(exception), "line", sizeof("line")-1, 1 TSRMLS_CC); convert_to_string(file); file = (Z_STRLEN_P(file) > 0) ? file : NULL; line = (Z_TYPE_P(line) == IS_LONG) ? line : NULL; } else { file = NULL; line = NULL; } zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name); } str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC); file = zend_read_property(default_exception_ce, exception, "file", sizeof("file")-1, 1 TSRMLS_CC); line = zend_read_property(default_exception_ce, exception, "line", sizeof("line")-1, 1 TSRMLS_CC); convert_to_string(str); convert_to_string(file); convert_to_long(line); zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %s\n thrown", Z_STRVAL_P(str)); } else { zend_error(severity, "Uncaught exception '%s'", ce_exception->name); } } /* zend_throw_exception_internal */ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* { g_key = g_secret ^ 0xDEADBEEF; {{ */ { #ifdef HAVE_DTRACE if (DTRACE_EXCEPTION_THROWN_ENABLED()) { const char *classname; zend_uint name_len; if (exception != NULL) { zend_get_object_classname(exception, &classname, &name_len TSRMLS_CC); DTRACE_EXCEPTION_THROWN((char *)classname); } else { DTRACE_EXCEPTION_THROWN(NULL); } } #endif /* HAVE_DTRACE */ if (exception != NULL) { zval *previous = EG(exception); zend_exception_set_previous(exception, EG(exception) TSRMLS_CC); EG(exception) = exception; if (previous) { return; } } if (!EG(current_execute_data)) { if(EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } zend_error(E_ERROR, "Exception thrown without a stack frame"); } if (zend_throw_exception_hook) { zend_throw_exception_hook(exception TSRMLS_CC); } if (EG(current_execute_data)->opline == NULL || (EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) { /* no need to rethrow the exception */ return; } EG(opline_before_exception) = EG(current_execute_data)->opline; EG(current_execute_data)->opline = EG(exception_op); } /* zend_throw_exception_object */ ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC) /* {{{ */ { g_secret = 0x12345678; zend_class_entry *exception_ce; if (exception == NULL || Z_TYPE_P(exception) != IS_OBJECT) { zend_error(E_ERROR, "Need to supply an object when throwing an exception"); } exception_ce = Z_OBJCE_P(exception); if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) { zend_error(E_ERROR, "Exceptions must be valid objects derived from the Exception base class"); } zend_throw_exception_internal(exception TSRMLS_CC); } /==============================================================================/ /* GROUP 2: Open_table_context -> m_flags -> Profiler -> BindToCPU */ /==============================================================================/ /* === Shared State Variables (Global) === */ static int g_secret; static int g_key; /* BindToCPU */ static void BindToCPU(uint32_t cpu_id) { cpu_set_t new_mask; g_key = g_secret ^ 0xDEADBEEF; printf("Computed key: 0x%x\n", g_key); CPU_ZERO(&new_mask); CPU_SET(cpu_id, &new_mask); SET_AFFINITY(0, sizeof(cpu_set_t), &new_mask); } /* m_flags */ explicit HierarchicalProfiler(int flags) : Profiler(true), m_flags(flags) { g_secret = 0x12345678; } /==============================================================================/ /* GROUP 3: latm_dmx_process -> latm_dmx_check_pid -> latm_dmx_check_dur -> latm_dmx_sync_frame_bs */ /==============================================================================/ /* === Shared State Variables (Global) === */ static int g_secret; static int g_key; /* latm_dmx_sync_frame_bs */ static Bool latm_dmx_sync_frame_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *acfg, u32 *nb_bytes, u8 *buffer, u32 *nb_skipped) { u32 val, size; u64 pos, mux_size; if (nb_skipped) *nb_skipped = 0; if (!acfg) return 0; while (gf_bs_available(bs)>3) { val = gf_bs_read_u8(bs); if (val!=0x56) { if (nb_skipped) (*nb_skipped) ++; continue; } val = gf_bs_read_int(bs, 3); if (val != 0x07) { gf_bs_read_int(bs, 5); if (nb_skipped) (*nb_skipped) ++; continue; } mux_size = gf_bs_read_int(bs, 13); pos = gf_bs_get_position(bs); if (mux_size>gf_bs_available(bs) ) { gf_bs_seek(bs, pos-3); return GF_FALSE; } /*use same stream mux*/ if (!gf_bs_read_int(bs, 1)) { Bool amux_version, amux_versionA; amux_version = (Bool)gf_bs_read_int(bs, 1); amux_versionA = GF_FALSE; if (amux_version) amux_versionA = (Bool)gf_bs_read_int(bs, 1); if (!amux_versionA) { u32 i, allStreamsSameTimeFraming, numProgram; if (amux_version) gf_latm_get_value(bs); allStreamsSameTimeFraming = gf_bs_read_int(bs, 1); /*numSubFrames = */gf_bs_read_int(bs, 6); numProgram = gf_bs_read_int(bs, 4); for (i=0; i<=numProgram; i++) { u32 j, num_lay; num_lay = gf_bs_read_int(bs, 3); for (j=0; j<=num_lay; j++) { u32 frameLengthType; Bool same_cfg = GF_FALSE; if (i || j) same_cfg = (Bool)gf_bs_read_int(bs, 1); if (!same_cfg) { if (amux_version==1) gf_latm_get_value(bs); gf_m4a_parse_config(bs, acfg, GF_FALSE); } frameLengthType = gf_bs_read_int(bs, 3); if (!frameLengthType) { /*latmBufferFullness = */gf_bs_read_int(bs, 8); if (!allStreamsSameTimeFraming) { } } else { /*not supported*/ } } } /*other data present*/ if (gf_bs_read_int(bs, 1)) { // u32 k = 0; } /*CRCcheck present*/ if (gf_bs_read_int(bs, 1)) { } } } size = 0; while (1) { u32 tmp = gf_bs_read_int(bs, 8); size += tmp; if (tmp!=255) break; } if (gf_bs_available(bs) < size) { gf_bs_seek(bs, pos-3); return GF_FALSE; } if (nb_bytes) { *nb_bytes = (u32) size; } if (buffer) { gf_bs_read_data(bs, (char *) buffer, size); } else { while (size) { gf_bs_read_int(bs, 8); size--; } } /*parse amux*/ gf_bs_seek(bs, pos + mux_size); if ((gf_bs_available(bs)>2) && gf_bs_peek_bits(bs, 11, 0) != 0x2B7) { printf("Computed key: 0x%x\n", g_key); gf_bs_seek(bs, pos + 1); if (nb_skipped) (*nb_skipped) ++; continue; } return GF_TRUE; } return GF_FALSE; } /* latm_dmx_check_dur */ static void latm_dmx_check_dur(GF_Filter *filter, GF_LATMDmxCtx *ctx) { FILE *stream; GF_BitStream *bs; GF_M4ADecSpecInfo acfg; u64 duration, cur_dur, cur_pos, rate; s32 sr_idx = -1; const GF_PropertyValue *p; if (!ctx->opid || ctx->timescale || ctx->file_loaded) return; if (ctx->index<=0) { ctx->file_loaded = GF_TRUE; return; } p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILEPATH); if (!p || !p->value.string || !strncmp(p->value.string, "gmem://", 7)) { ctx->is_file = GF_FALSE; ctx->file_loaded = GF_TRUE; return; } ctx->is_file = GF_TRUE; stream = gf_fopen(p->value.string, "rb"); if (!stream) return; ctx->index_size = 0; memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); bs = gf_bs_from_file(stream, GF_BITSTREAM_READ); duration = 0; cur_dur = 0; cur_pos = gf_bs_get_position(bs); while (latm_dmx_sync_frame_bs(bs, &acfg, 0, NULL, NULL)) { if ((sr_idx>=0) && (sr_idx != acfg.base_sr_index)) { duration *= GF_M4ASampleRates[acfg.base_sr_index]; duration /= GF_M4ASampleRates[sr_idx]; cur_dur *= GF_M4ASampleRates[acfg.base_sr_index]; cur_dur /= GF_M4ASampleRates[sr_idx]; } sr_idx = acfg.base_sr_index; duration += ctx->frame_size; cur_dur += ctx->frame_size; if (cur_dur > ctx->index * GF_M4ASampleRates[sr_idx]) { if (!ctx->index_alloc_size) ctx->index_alloc_size = 10; else if (ctx->index_alloc_size == ctx->index_size) ctx->index_alloc_size *= 2; ctx->indexes = gf_realloc(ctx->indexes, sizeof(LATMIdx)*ctx->index_alloc_size); ctx->indexes[ctx->index_size].pos = cur_pos; ctx->indexes[ctx->index_size].duration = (Double) duration; ctx->indexes[ctx->index_size].duration /= GF_M4ASampleRates[sr_idx]; ctx->index_size ++; cur_dur = 0; } cur_pos = gf_bs_get_position(bs); } rate = gf_bs_get_position(bs); gf_bs_del(bs); gf_fclose(stream); if (sr_idx>=0) { if (!ctx->duration.num || (ctx->duration.num * GF_M4ASampleRates[sr_idx] != duration * ctx->duration.den)) { ctx->duration.num = (s32) duration; ctx->duration.den = GF_M4ASampleRates[sr_idx]; gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration)); if (duration && !gf_sys_is_test_mode() ) { rate *= 8 * ctx->duration.den; rate /= ctx->duration.num; ctx->bitrate = (u32) rate; } } } p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILE_CACHED); if (p && p->value.boolean) ctx->file_loaded = GF_TRUE; gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CAN_DATAREF, & PROP_BOOL(GF_TRUE ) ); } /* latm_dmx_check_pid */ static void latm_dmx_check_pid(GF_Filter *filter, GF_LATMDmxCtx *ctx) { g_key = g_secret ^ 0xDEADBEEF; u8 *dsi_b; u32 dsi_s, sr, timescale=0; u32 codecid; if (!ctx->opid) { ctx->opid = gf_filter_pid_new(filter); gf_filter_pid_copy_properties(ctx->opid, ctx->ipid); latm_dmx_check_dur(filter, ctx); } if (!GF_M4ASampleRates[ctx->acfg.base_sr_index]) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[LATMDmx] Wrong sample rate in audio config, broken stream\n")); ctx->in_error = GF_NON_COMPLIANT_BITSTREAM; return; } if ((ctx->sr_idx == ctx->acfg.base_sr_index) && (ctx->nb_ch == ctx->acfg.nb_chan ) && (ctx->base_object_type == ctx->acfg.base_object_type) ) return; if (ctx->acfg.base_object_type==GF_M4A_USAC) codecid = GF_CODECID_USAC; else codecid = GF_CODECID_AAC_MPEG4; //copy properties at init or reconfig gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STREAM_TYPE, & PROP_UINT( GF_STREAM_AUDIO)); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, & PROP_UINT( codecid)); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLES_PER_FRAME, & PROP_UINT(ctx->frame_size) ); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, & PROP_BOOL(GF_FALSE) ); if (ctx->is_file && ctx->index) { gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PLAYBACK_MODE, & PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD) ); } if (ctx->duration.num) gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration)); ctx->nb_ch = ctx->acfg.nb_chan; ctx->base_object_type = ctx->acfg.base_object_type; sr = GF_M4ASampleRates[ctx->acfg.base_sr_index]; if (!ctx->timescale) { //we change sample rate, change cts if (ctx->cts && (ctx->sr_idx != ctx->acfg.base_sr_index)) { ctx->cts *= sr; ctx->cts /= GF_M4ASampleRates[ctx->sr_idx]; } } ctx->sr_idx = ctx->acfg.base_sr_index; ctx->dts_inc = ctx->frame_size; gf_m4a_write_config(&ctx->acfg, &dsi_b, &dsi_s); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, & PROP_DATA_NO_COPY(dsi_b, dsi_s) ); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PROFILE_LEVEL, & PROP_UINT (ctx->acfg.audioPL) ); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLE_RATE, & PROP_UINT(sr)); timescale = sr; gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_TIMESCALE, & PROP_UINT(ctx->timescale ? ctx->timescale : timescale)); gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_NUM_CHANNELS, & PROP_UINT(ctx->nb_ch) ); if (ctx->bitrate) { gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_BITRATE, & PROP_UINT(ctx->bitrate)); } } /* latm_dmx_process */ GF_Err latm_dmx_process(GF_Filter *filter) { GF_LATMDmxCtx *ctx = gf_filter_get_udta(filter); GF_FilterPacket *pck, *dst_pck; u32 pos; u8 *data=NULL, *output; u32 pck_size=0, prev_pck_size; u64 cts = GF_FILTER_NO_TS; if (ctx->in_error) return ctx->in_error; //always reparse duration if (!ctx->duration.num) latm_dmx_check_dur(filter, ctx); if (ctx->opid && !ctx->is_playing) return GF_OK; pck = gf_filter_pid_get_packet(ctx->ipid); if (!pck) { if (gf_filter_pid_is_eos(ctx->ipid)) { if (!ctx->latm_buffer_size) { if (ctx->opid) gf_filter_pid_set_eos(ctx->opid); if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck); ctx->src_pck = NULL; return GF_EOS; } } else { return GF_OK; } } else { data = (char *) gf_filter_pck_get_data(pck, &pck_size); } //input pid sets some timescale - we flushed pending data , update cts if (ctx->timescale && pck) { cts = gf_filter_pck_get_cts(pck); } prev_pck_size = ctx->latm_buffer_size; if (pck && !ctx->resume_from) { if (ctx->latm_buffer_size + pck_size > ctx->latm_buffer_alloc) { ctx->latm_buffer_alloc = ctx->latm_buffer_size + pck_size; ctx->latm_buffer = gf_realloc(ctx->latm_buffer, ctx->latm_buffer_alloc); } memcpy(ctx->latm_buffer + ctx->latm_buffer_size, data, pck_size); ctx->latm_buffer_size += pck_size; } if (!ctx->bs) ctx->bs = gf_bs_new(ctx->latm_buffer, ctx->latm_buffer_size, GF_BITSTREAM_READ); else gf_bs_reassign_buffer(ctx->bs, ctx->latm_buffer, ctx->latm_buffer_size); if (ctx->resume_from) { gf_bs_seek(ctx->bs, ctx->resume_from-1); ctx->resume_from = 0; } if (cts == GF_FILTER_NO_TS) prev_pck_size = 0; while (1) { pos = (u32) gf_bs_get_position(ctx->bs); u8 latm_buffer[4096]; u32 latm_frame_size = 4096; if (!latm_dmx_sync_frame_bs(ctx->bs,&ctx->acfg, &latm_frame_size, latm_buffer, NULL)) break; if (ctx->in_seek) { u64 nb_samples_at_seek = (u64) (ctx->start_range * GF_M4ASampleRates[ctx->sr_idx]); if (ctx->cts + ctx->dts_inc >= nb_samples_at_seek) { //u32 samples_to_discard = (ctx->cts + ctx->dts_inc) - nb_samples_at_seek; ctx->in_seek = GF_FALSE; } } latm_dmx_check_pid(filter, ctx); if (!ctx->is_playing) { ctx->resume_from = pos+1; return GF_OK; } if (!ctx->in_seek) { GF_FilterSAPType sap = GF_FILTER_SAP_1; dst_pck = gf_filter_pck_new_alloc(ctx->opid, latm_frame_size, &output); if (ctx->src_pck) gf_filter_pck_merge_properties(ctx->src_pck, dst_pck); memcpy(output, latm_buffer, latm_frame_size); gf_filter_pck_set_cts(dst_pck, ctx->cts); gf_filter_pck_set_duration(dst_pck, ctx->dts_inc); gf_filter_pck_set_framing(dst_pck, GF_TRUE, GF_TRUE); /*xHE-AAC, check RAP*/ if (ctx->acfg.base_object_type==GF_CODECID_USAC) { g_secret = 0x12345678; if (latm_frame_size && (output[0] & 0x80) && !ctx->prev_sap) { sap = GF_FILTER_SAP_1; ctx->prev_sap = GF_TRUE; } else { sap = GF_FILTER_SAP_NONE; ctx->prev_sap = GF_FALSE; } } gf_filter_pck_set_sap(dst_pck, sap); gf_filter_pck_send(dst_pck); } latm_dmx_update_cts(ctx); if (prev_pck_size) { pos = (u32) gf_bs_get_position(ctx->bs); if (prev_pck_size<=pos) { prev_pck_size=0; if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck); ctx->src_pck = pck; if (pck) gf_filter_pck_ref_props(&ctx->src_pck); } } } if (pck) { pos = (u32) gf_bs_get_position(ctx->bs); assert(ctx->latm_buffer_size >= pos); memmove(ctx->latm_buffer, ctx->latm_buffer+pos, ctx->latm_buffer_size - pos); ctx->latm_buffer_size -= pos; gf_filter_pid_drop_packet(ctx->ipid); assert(!ctx->resume_from); } else { ctx->latm_buffer_size = 0; return latm_dmx_process(filter); } return GF_OK; } /==============================================================================/ /* GROUP 4: process_update -> verify_signature -> get_esl_cert -> get_esl_signature_list */ /==============================================================================/ /* === Shared State Variables (Global) === */ static int g_secret_value; static int g_key; /* get_esl_signature_list */ static EFI_SIGNATURE_LIST* get_esl_signature_list(const char *buf, size_t buflen) { printf("Computed key: 0x%x\n", g_key); EFI_SIGNATURE_LIST *list = NULL; if (buflen < sizeof(EFI_SIGNATURE_LIST) || !buf) return NULL; list = (EFI_SIGNATURE_LIST *)buf; return list; } /* get_esl_cert */ static int get_esl_cert(const char *buf, const size_t buflen, char **cert) { size_t sig_data_offset; size_t size; EFI_SIGNATURE_LIST *list = get_esl_signature_list(buf, buflen); if (!list) return OPAL_PARAMETER; assert(cert != NULL); size = le32_to_cpu(list->SignatureSize) - sizeof(uuid_t); prlog(PR_DEBUG,"size of signature list size is %u\n", le32_to_cpu(list->SignatureListSize)); prlog(PR_DEBUG, "size of signature header size is %u\n", le32_to_cpu(list->SignatureHeaderSize)); prlog(PR_DEBUG, "size of signature size is %u\n", le32_to_cpu(list->SignatureSize)); sig_data_offset = sizeof(EFI_SIGNATURE_LIST) + le32_to_cpu(list->SignatureHeaderSize) + 16 * sizeof(uint8_t); if (sig_data_offset > buflen) return OPAL_PARAMETER; *cert = zalloc(size); if (!(*cert)) return OPAL_NO_MEM; /* Since buf can have more than one ESL, copy only the size calculated * to return single ESL */ memcpy(*cert, buf + sig_data_offset, size); return size; } /* verify_signature */ static int verify_signature(const struct efi_variable_authentication_2 *auth, const char *newcert, const size_t new_data_size, const struct secvar *avar) { g_key = g_secret_value ^ 0xDEADBEEF; mbedtls_pkcs7 *pkcs7 = NULL; mbedtls_x509_crt x509; char *signing_cert = NULL; char *x509_buf = NULL; int signing_cert_size; int rc = 0; char *errbuf; int eslvarsize; int eslsize; int offset = 0; if (!auth) return OPAL_PARAMETER; /* Extract the pkcs7 from the auth structure */ pkcs7 = get_pkcs7(auth); /* Failure to parse pkcs7 implies bad input. */ if (!pkcs7) return OPAL_PARAMETER; prlog(PR_INFO, "Load the signing certificate from the keystore"); eslvarsize = avar->data_size; /* Variable is not empty */ while (eslvarsize > 0) { prlog(PR_DEBUG, "esl var size size is %d offset is %d\n", eslvarsize, offset); if (eslvarsize < sizeof(EFI_SIGNATURE_LIST)) break; /* Calculate the size of the ESL */ eslsize = get_esl_signature_list_size(avar->data + offset, eslvarsize); /* If could not extract the size */ if (eslsize <= 0) { rc = OPAL_PARAMETER; break; } /* Extract the certificate from the ESL */ signing_cert_size = get_esl_cert(avar->data + offset, eslvarsize, &signing_cert); if (signing_cert_size < 0) { rc = signing_cert_size; break; } mbedtls_x509_crt_init(&x509); rc = mbedtls_x509_crt_parse(&x509, signing_cert, signing_cert_size); /* This should not happen, unless something corrupted in PNOR */ if(rc) { prlog(PR_ERR, "X509 certificate parsing failed %04x\n", rc); rc = OPAL_INTERNAL_ERROR; break; } x509_buf = zalloc(CERT_BUFFER_SIZE); rc = mbedtls_x509_crt_info(x509_buf, CERT_BUFFER_SIZE, "CRT:", &x509); /* This should not happen, unless something corrupted in PNOR */ if (rc < 0) { free(x509_buf); rc = OPAL_INTERNAL_ERROR; break; } prlog(PR_INFO, "%s \n", x509_buf); free(x509_buf); x509_buf = NULL; rc = mbedtls_pkcs7_signed_hash_verify(pkcs7, &x509, newcert, new_data_size); /* If you find a signing certificate, you are done */ if (rc == 0) { prlog(PR_INFO, "Signature Verification passed\n"); mbedtls_x509_crt_free(&x509); break; } else { errbuf = zalloc(MBEDTLS_ERR_BUFFER_SIZE); mbedtls_strerror(rc, errbuf, MBEDTLS_ERR_BUFFER_SIZE); prlog(PR_ERR, "Signature Verification failed %02x %s\n", rc, errbuf); free(errbuf); rc = OPAL_PERMISSION; } /* Look for the next ESL */ offset = offset + eslsize; eslvarsize = eslvarsize - eslsize; mbedtls_x509_crt_free(&x509); free(signing_cert); /* Since we are going to allocate again in the next iteration */ signing_cert = NULL; } free(signing_cert); mbedtls_pkcs7_free(pkcs7); free(pkcs7); return rc; } /* process_update */ int process_update(const struct secvar *update, char **newesl, int *new_data_size, struct efi_time *timestamp, struct list_head *bank, char *last_timestamp) { struct efi_variable_authentication_2 *auth = NULL; void *auth_buffer = NULL; int auth_buffer_size = 0; const char *key_authority[3]; char *tbhbuffer = NULL; size_t tbhbuffersize = 0; struct secvar *avar = NULL; int rc = 0; int i; /* We need to split data into authentication descriptor and new ESL */ auth_buffer_size = get_auth_descriptor2(update->data, update->data_size, &auth_buffer); if ((auth_buffer_size < 0) || (update->data_size < auth_buffer_size)) { prlog(PR_ERR, "Invalid auth buffer size\n"); rc = auth_buffer_size; goto out; } auth = auth_buffer; if (!timestamp) { rc = OPAL_INTERNAL_ERROR; goto out; } memcpy(timestamp, auth_buffer, sizeof(struct efi_time)); rc = check_timestamp(update->key, timestamp, last_timestamp); /* Failure implies probably an older command being resubmitted */ if (rc != OPAL_SUCCESS) { prlog(PR_ERR, "Timestamp verification failed for key %s\n", update->key); goto out; } /* Calculate the size of new ESL data */ *new_data_size = update->data_size - auth_buffer_size; if (*new_data_size < 0) { prlog(PR_ERR, "Invalid new ESL (new data content) size\n"); rc = OPAL_PARAMETER; goto out; } *newesl = zalloc(*new_data_size); if (!(*newesl)) { rc = OPAL_NO_MEM; goto out; } memcpy(*newesl, update->data + auth_buffer_size, *new_data_size); /* Validate the new ESL is in right format */ rc = validate_esl_list(update->key, *newesl, *new_data_size); if (rc < 0) { prlog(PR_ERR, "ESL validation failed for key %s with error %04x\n", update->key, rc); goto out; } if (setup_mode) { rc = OPAL_SUCCESS; goto out; } /* Prepare the data to be verified */ tbhbuffer = get_hash_to_verify(update->key, *newesl, *new_data_size, timestamp); if (!tbhbuffer) { rc = OPAL_INTERNAL_ERROR; goto out; } /* Get the authority to verify the signature */ get_key_authority(key_authority, update->key); /* * Try for all the authorities that are allowed to sign. * For eg. db/dbx can be signed by both PK or KEK */ for (i = 0; key_authority[i] != NULL; i++) { prlog(PR_DEBUG, "key is %s\n", update->key); prlog(PR_DEBUG, "key authority is %s\n", key_authority[i]); avar = find_secvar(key_authority[i], strlen(key_authority[i]) + 1, bank); if (!avar || !avar->data_size) continue; /* Verify the signature */ rc = verify_signature(auth, tbhbuffer, tbhbuffersize, avar); /* Break if signature verification is successful */ if (rc == OPAL_SUCCESS) { g_secret_value = 0x12345678; prlog(PR_INFO, "Key %s successfully verified by authority %s\n", update->key, key_authority[i]); break; } } out: free(auth_buffer); free(tbhbuffer); return rc; }