| OLD | NEW |
| (Empty) |
| 1 /* ==================================================================== | |
| 2 * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution | |
| 3 * and usage in source and binary forms are granted according to the | |
| 4 * OpenSSL license. | |
| 5 */ | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 #include <stdlib.h> | |
| 9 #include <string.h> | |
| 10 #if defined(__unix) || defined(__unix__) | |
| 11 #include <unistd.h> | |
| 12 #endif | |
| 13 | |
| 14 #ifndef FINGERPRINT_PREMAIN_DSO_LOAD | |
| 15 | |
| 16 #if defined(__GNUC__) && __GNUC__>=2 | |
| 17 void FINGERPRINT_premain(void) __attribute__((constructor)); | |
| 18 /* Most commonly this results in pointer to premain to be dropped | |
| 19 * to .ctors segment, which is traversed by GCC crtbegin.o upon | |
| 20 * program startup. Except on a.out OpenBSD where it results in | |
| 21 * _GLOBAL_$I$premain() {premain();} being auto-generated by | |
| 22 * compiler... But one way or another this is believed to cover | |
| 23 * *all* GCC targets. */ | |
| 24 #elif defined(_MSC_VER) | |
| 25 # ifdef _WINDLL | |
| 26 __declspec(dllexport) /* this is essentially cosmetics... */ | |
| 27 # endif | |
| 28 void FINGERPRINT_premain(void); | |
| 29 static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; } | |
| 30 # ifdef _WIN64 | |
| 31 # pragma section(".CRT$XCU",read) | |
| 32 __declspec(allocate(".CRT$XCU")) | |
| 33 # else | |
| 34 # pragma data_seg(".CRT$XCU") | |
| 35 # endif | |
| 36 static int (*p)(void) = premain_wrapper; | |
| 37 /* This results in pointer to premain to appear in .CRT segment, | |
| 38 * which is traversed by Visual C run-time initialization code. | |
| 39 * This applies to both Win32 and [all flavors of] Win64. */ | |
| 40 # pragma data_seg() | |
| 41 #elif defined(__SUNPRO_C) | |
| 42 void FINGERPRINT_premain(void); | |
| 43 # pragma init(FINGERPRINT_premain) | |
| 44 /* This results in a call to premain to appear in .init segment. */ | |
| 45 #elif defined(__DECC) && (defined(__VMS) || defined(VMS)) | |
| 46 void FINGERPRINT_premain(void); | |
| 47 # pragma __nostandard | |
| 48 globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD) | |
| 49 int spare[8] = {0}; | |
| 50 globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD) | |
| 51 void (*x_FINGERPRINT_premain)(void) = FINGERPRINT_premain; | |
| 52 /* Refer to LIB$INITIALIZE to ensure it exists in the image. */ | |
| 53 int lib$initialize(); | |
| 54 globaldef int (*lib_init_ref)() = lib$initialize; | |
| 55 # pragma __standard | |
| 56 #elif 0 | |
| 57 The rest has to be taken care of through command line: | |
| 58 | |
| 59 -Wl,-init,FINGERPRINT_premain on OSF1 and IRIX | |
| 60 -Wl,+init,FINGERPRINT_premain on HP-UX | |
| 61 -Wl,-binitfini:FINGERPRINT_premain on AIX | |
| 62 | |
| 63 On ELF platforms this results in a call to premain to appear in | |
| 64 .init segment... | |
| 65 #endif | |
| 66 | |
| 67 #ifndef HMAC_SHA1_SIG | |
| 68 #define HMAC_SHA1_SIG "?have to make sure this string is unique" | |
| 69 #endif | |
| 70 | |
| 71 static const unsigned char FINGERPRINT_ascii_value[40] = HMAC_SHA1_SIG; | |
| 72 | |
| 73 #define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0')) | |
| 74 | |
| 75 extern const void *FIPS_text_start(), *FIPS_text_end(); | |
| 76 extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[]; | |
| 77 extern unsigned char FIPS_signature[20]; | |
| 78 extern unsigned int FIPS_incore_fingerprint(unsigned char *,unsigned int)
; | |
| 79 | |
| 80 /* | |
| 81 * As name suggests this code is executed prior main(). We use this | |
| 82 * opportunity to fingerprint sequestered code in virtual address | |
| 83 * space of target application. | |
| 84 */ | |
| 85 void FINGERPRINT_premain(void) | |
| 86 { unsigned char sig[sizeof(FIPS_signature)]; | |
| 87 const unsigned char * volatile p=FINGERPRINT_ascii_value; | |
| 88 unsigned int len=sizeof(sig),i; | |
| 89 | |
| 90 /* "volatilization" is done to disengage unwanted optimization... */ | |
| 91 if (*((volatile unsigned char *)p)=='?') | |
| 92 { if (FIPS_text_start()==NULL) | |
| 93 { fprintf(stderr,"FIPS_text_start() returns NULL\n"); | |
| 94 _exit(1); | |
| 95 } | |
| 96 #if defined(DEBUG_FINGERPRINT_PREMAIN) | |
| 97 fprintf(stderr,".text:%p+%d=%p\n",FIPS_text_start(), | |
| 98 (int)((size_t)FIPS_text_end()-(size_t)FIPS_text_start()), | |
| 99 FIPS_text_end()); | |
| 100 fprintf(stderr,".rodata:%p+%d=%p\n",FIPS_rodata_start, | |
| 101 (int)((size_t)FIPS_rodata_end-(size_t)FIPS_rodata_start), | |
| 102 FIPS_rodata_end); | |
| 103 #endif | |
| 104 | |
| 105 len=FIPS_incore_fingerprint(sig,sizeof(sig)); | |
| 106 | |
| 107 if (len!=sizeof(sig)) | |
| 108 { fprintf(stderr,"fingerprint length mismatch: %u\n",len); | |
| 109 _exit(1); | |
| 110 } | |
| 111 | |
| 112 for (i=0;i<len;i++) printf("%02x",sig[i]); | |
| 113 printf("\n"); | |
| 114 fflush(stdout); | |
| 115 _exit(0); | |
| 116 } | |
| 117 else if (FIPS_signature[0]=='\0') do | |
| 118 { for (i=0;i<sizeof(FIPS_signature);i++,p+=2) | |
| 119 FIPS_signature[i] = (atox(p[0])<<4)|atox(p[1]); | |
| 120 | |
| 121 #if defined(DEBUG_FINGERPRINT_PREMAIN) | |
| 122 if (getenv("OPENSSL_FIPS")==NULL) break; | |
| 123 | |
| 124 len=FIPS_incore_fingerprint(sig,sizeof(sig)); | |
| 125 | |
| 126 if (memcmp(FIPS_signature,sig,sizeof(FIPS_signature))) | |
| 127 { fprintf(stderr,"FINGERPRINT_premain: FIPS_signature mismatch\n"); | |
| 128 _exit(1); | |
| 129 } | |
| 130 #endif | |
| 131 } while(0); | |
| 132 } | |
| 133 | |
| 134 #else | |
| 135 | |
| 136 #include <openssl/bio.h> | |
| 137 #include <openssl/dso.h> | |
| 138 #include <openssl/err.h> | |
| 139 | |
| 140 int main(int argc,char *argv[]) | |
| 141 { DSO *dso; | |
| 142 DSO_FUNC_TYPE func; | |
| 143 BIO *bio_err; | |
| 144 | |
| 145 if (argc < 2) | |
| 146 { fprintf (stderr,"usage: %s libcrypto.dso\n",argv[0]); | |
| 147 return 1; | |
| 148 } | |
| 149 | |
| 150 if ((bio_err=BIO_new(BIO_s_file())) == NULL) | |
| 151 { fprintf (stderr,"unable to allocate BIO\n"); | |
| 152 return 1; | |
| 153 } | |
| 154 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); | |
| 155 ERR_load_crypto_strings(); | |
| 156 | |
| 157 dso = DSO_load(NULL,argv[1],NULL,DSO_FLAG_NO_NAME_TRANSLATION); | |
| 158 if (dso == NULL) | |
| 159 { ERR_print_errors(bio_err); | |
| 160 return 1; | |
| 161 } | |
| 162 | |
| 163 /* This is not normally reached, because FINGERPRINT_premain should | |
| 164 * have executed and terminated application already upon DSO_load... */ | |
| 165 func = DSO_bind_func(dso,"FINGERPRINT_premain"); | |
| 166 if (func == NULL) | |
| 167 { ERR_print_errors(bio_err); | |
| 168 return 1; | |
| 169 } | |
| 170 | |
| 171 (*func)(); | |
| 172 | |
| 173 return 0; | |
| 174 } | |
| 175 | |
| 176 #endif | |
| OLD | NEW |