void handle_sha1(array_t *out, bio_t *in) { sha1_ctx_t ctx; char hex[sizeof(ctx.hash) * 2]; size_t r; sha1_init(&ctx); do { r = bio_feed(in); sha1_update(&ctx, BIO_PEEK(in), r); BIO_SEEK(in, r); } while (r > 0); sha1_finish(&ctx); array_append(out, hex, fmt_hex_pad(hex, ctx.hash, sizeof(ctx.hash))); array_append_null(out); }
// Retrieve the tag size_t mintls_hash_finish( mintls_hash_context * ctx, // (I/O) Context uint8_t * tag // (O) Tag ) { switch (ctx->type) { case MinTLS_SHA_160: return sha1_finish((struct sha1_ctx *)ctx,tag); case MinTLS_SHA_256: case MinTLS_SHA_224: return sha2_finish((struct sha2_ctx *)ctx,tag); case MinTLS_SHA_384: case MinTLS_SHA_512: return sha4_finish((struct sha4_ctx *)ctx,tag); default: return 0; } }
/* * SHA-1 HMAC context setup */ void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen ) { if( keylen > 64 ) // Key shortened if greater than BLOCK SIZE (64 bytes) { sha1_context cty; sha1_init(&cty); sha1_starts(&cty); sha1_update(&cty, key, keylen); // Get the 20 char digest of the key sha1_finish(&cty, ctx->key); // Store the digest in ctx.key sha1_free(&cty); ctx->keyLen = 20; } else { ctx->keyLen = keylen; // Use the key as is memcpy(ctx->key, key, keylen); // Store the key in ctx.key } }
static void processFile(int fd, const char *filename) { sha1_ctx_t sha1; byte bigbuf[4096]; int n; sha1_init(&sha1); while ((n = read(fd, bigbuf, sizeof(bigbuf))) > 0) sha1_process(&sha1, bigbuf, n); if (n == -1) { fprintf(stderr, "Error occured during reading %s: %s\n", filename, strerror(errno)); return; } sha1_finish(&sha1); for (n = 0; n < 20; n++) printf("%02x", sha1.buf[n]); printf(" %s\n", filename); }
/** * @brief Create content hash key for a byte array * * Create a content hash key for the given buffer and size. * * @param key pointer to the receiving chkey_t * @param buff byte array of data to hash * @param size size of byte array to has * * @result zero on success */ int key_chk(chkey_t *key, const void *buff, size_t size) { key_state_t ks; FUN("key_chk"); sha1_init(&ks.ss); sha1_append(&ks.ss, buff, size); sha1_finish(&ks.ss, &key->sha1); key->log2size = log2size(size); key->type[0] = MSB(K_CHK); key->type[1] = LSB(K_CHK); ek5_init(&ks.es); ek5_append(&ks.es, buff, size); ek5_finish(&ks.es, &key->ek5); key->padding = 0; return 0; }
/** * @brief Create the public SSK for a private SSK * * Create a public key from a private key, * simply by hashing the hex string of the SHA1 digest. * * @param key pointer to a key to receive the public SSK * @param ssk pointer to a key containing a private SSK * * @result zero on success */ int key_ssk_pub_from_priv(chkey_t *key, const chkey_t *ssk) { char hex[SHA1SIZE*2+1]; sha1_state_t sha1; size_t size; FUN("key_ssk_pub_from_priv"); size = pm_snprintf(hex, sizeof(hex), "%s", sha1_hexstr(&ssk->sha1)); sha1_init(&sha1); sha1_append(&sha1, hex, size); sha1_finish(&sha1, &key->sha1); key->type[0] = MSB(K_SSK_P); key->type[1] = LSB(K_SSK_P); key->log2size = log2size(size); memset(&key->ek5, 0, sizeof(key->ek5)); return 0; }
int main(int argc, char *argv[]) { int res = EXIT_FAILURE; int buflen; int err; struct stat st; char *buf; struct planex_hdr *hdr; sha1_context ctx; uint32_t t = HOST_TO_BE32(2); FILE *outfile, *infile; progname = basename(argv[0]); while ( 1 ) { int c; c = getopt(argc, argv, "i:o:v:h"); if (c == -1) break; switch (c) { case 'i': ifname = optarg; break; case 'o': ofname = optarg; break; case 'v': version = optarg; break; case 'h': usage(EXIT_SUCCESS); break; default: usage(EXIT_FAILURE); break; } } if (ifname == NULL) { ERR("no input file specified"); goto err; } if (ofname == NULL) { ERR("no output file specified"); goto err; } err = stat(ifname, &st); if (err) { ERRS("stat failed on %s", ifname); goto err; } buflen = (st.st_size + 3) & ~3; buflen += sizeof(*hdr); buf = malloc(buflen); if (!buf) { ERR("no memory for buffer\n"); goto err; } memset(buf, 0xff, buflen); hdr = (struct planex_hdr *)buf; hdr->datalen = HOST_TO_BE32(buflen - sizeof(*hdr)); hdr->unk1[0] = 0x04; hdr->unk1[1] = 0x08; snprintf(hdr->version, sizeof(hdr->version), "%s", version); infile = fopen(ifname, "r"); if (infile == NULL) { ERRS("could not open \"%s\" for reading", ifname); goto err_free; } errno = 0; fread(buf + sizeof(*hdr), st.st_size, 1, infile); if (errno != 0) { ERRS("unable to read from file %s", ifname); goto err_close_in; } sha1_starts(&ctx); sha1_update(&ctx, (uchar *) &t, sizeof(t)); sha1_update(&ctx, buf + sizeof(*hdr), buflen - sizeof(*hdr)); sha1_finish(&ctx, hdr->sha1sum); outfile = fopen(ofname, "w"); if (outfile == NULL) { ERRS("could not open \"%s\" for writing", ofname); goto err_close_in; } errno = 0; fwrite(buf, buflen, 1, outfile); if (errno) { ERRS("unable to write to file %s", ofname); goto err_close_out; } res = EXIT_SUCCESS; out_flush: fflush(outfile); err_close_out: fclose(outfile); if (res != EXIT_SUCCESS) { unlink(ofname); } err_close_in: fclose(infile); err_free: free(buf); err: return res; }
/* Restore the checksum before writing */ hdr->prolog_checksum = checksum_ref; printf("Image checksum...OK!\n"); return 0; } #elif defined(CONFIG_ARMADA_3700) /* Armada 3700 */ static int check_image_header(void) { struct common_tim_data *hdr = (struct common_tim_data *)get_load_addr(); int image_num; u8 hash_160_output[SHA1_SUM_LEN]; u8 hash_256_output[SHA256_SUM_LEN]; sha1_context hash1_text; sha256_context hash256_text; u8 *hash_output; u32 hash_algorithm_id; u32 image_size_to_hash; u32 flash_entry_addr; u32 *hash_value; u32 internal_hash[HASH_SUM_LEN]; const u8 *buff; u32 num_of_image = hdr->num_images; u32 version = hdr->version; u32 trusted = hdr->trusted; /* bubt checksum validation only supports nontrusted images */ if (trusted == 1) { printf("bypass image validation, "); printf("only untrusted image is supported now\n"); return 0; } /* only supports image version 3.5 and 3.6 */ if (version != IMAGE_VERSION_3_5_0 && version != IMAGE_VERSION_3_6_0) { printf("Error: Unsupported Image version = 0x%08x\n", version); return -ENOEXEC; } /* validate images hash value */ for (image_num = 0; image_num < num_of_image; image_num++) { struct mvebu_image_info *info = (struct mvebu_image_info *)(get_load_addr() + sizeof(struct common_tim_data) + image_num * sizeof(struct mvebu_image_info)); hash_algorithm_id = info->hash_algorithm_id; image_size_to_hash = info->image_size_to_hash; flash_entry_addr = info->flash_entry_addr; hash_value = info->hash; buff = (const u8 *)(get_load_addr() + flash_entry_addr); if (image_num == 0) { /* * The first image includes hash values in its content. * For hash calculation, we need to save the original * hash values to a local variable that will be * copied back for comparsion and set all zeros to * the orignal hash values for calculating new value. * First image original format : * x...x (datum1) x...x(orig. hash values) x...x(datum2) * Replaced first image format : * x...x (datum1) 0...0(hash values) x...x(datum2) */ memcpy(internal_hash, hash_value, sizeof(internal_hash)); memset(hash_value, 0, sizeof(internal_hash)); } if (image_size_to_hash == 0) { printf("Warning: Image_%d hash checksum is disabled, ", image_num); printf("skip the image validation.\n"); continue; } switch (hash_algorithm_id) { case SHA1_SUM_LEN: sha1_starts(&hash1_text); sha1_update(&hash1_text, buff, image_size_to_hash); sha1_finish(&hash1_text, hash_160_output); hash_output = hash_160_output; break; case SHA256_SUM_LEN: sha256_starts(&hash256_text); sha256_update(&hash256_text, buff, image_size_to_hash); sha256_finish(&hash256_text, hash_256_output); hash_output = hash_256_output; break; default: printf("Error: Unsupported hash_algorithm_id = %d\n", hash_algorithm_id); return -ENOEXEC; } if (image_num == 0) memcpy(hash_value, internal_hash, sizeof(internal_hash)); if (memcmp(hash_value, hash_output, hash_algorithm_id) != 0) { printf("Error: Image_%d checksum is not correct\n", image_num); return -ENOEXEC; } } printf("Image checksum...OK!\n"); return 0; }
SEXP digest(SEXP Txt, SEXP Algo, SEXP Length, SEXP Skip, SEXP Leave_raw) { FILE *fp=0; char *txt; int algo = INTEGER_VALUE(Algo); int length = INTEGER_VALUE(Length); int skip = INTEGER_VALUE(Skip); int leaveRaw = INTEGER_VALUE(Leave_raw); SEXP result = NULL; char output[128+1], *outputp = output; /* 33 for md5, 41 for sha1, 65 for sha256, 128 for sha512; plus trailing NULL */ int nChar; int output_length = -1; if (IS_RAW(Txt)) { /* Txt is either RAW */ txt = (char*) RAW(Txt); nChar = LENGTH(Txt); } else { /* or a string */ txt = (char*) STRING_VALUE(Txt); nChar = strlen(txt); } if (skip>0) { if (skip>=nChar) nChar=0; else { nChar -= skip; txt += skip; } } if (length>=0 && length<nChar) nChar = length; switch (algo) { case 1: { /* md5 case */ md5_context ctx; output_length = 16; unsigned char md5sum[16]; int j; md5_starts( &ctx ); md5_update( &ctx, (uint8 *) txt, nChar); md5_finish( &ctx, md5sum ); memcpy(output, md5sum, 16); if (!leaveRaw) for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 2: { /* sha1 case */ int j; sha1_context ctx; output_length = 20; unsigned char sha1sum[20]; sha1_starts( &ctx ); sha1_update( &ctx, (uint8 *) txt, nChar); sha1_finish( &ctx, sha1sum ); memcpy(output, sha1sum, 20); if (!leaveRaw) for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 3: { /* crc32 case */ unsigned long val, l; l = nChar; val = digest_crc32(0L, 0, 0); val = digest_crc32(val, (unsigned char*) txt, (unsigned) l); sprintf(output, "%2.2x", (unsigned int) val); break; } case 4: { /* sha256 case */ int j; sha256_context ctx; output_length = 32; unsigned char sha256sum[32]; sha256_starts( &ctx ); sha256_update( &ctx, (uint8 *) txt, nChar); sha256_finish( &ctx, sha256sum ); memcpy(output, sha256sum, 32); if(!leaveRaw) for( j = 0; j < 32; j++ ) sprintf( output + j * 2, "%02x", sha256sum[j] ); break; } case 5: { /* sha2-512 case */ int j; SHA512_CTX ctx; output_length = SHA512_DIGEST_LENGTH; uint8_t sha512sum[output_length], *d = sha512sum; SHA512_Init(&ctx); SHA512_Update(&ctx, (uint8 *) txt, nChar); // Calling SHA512_Final, because SHA512_End will already // convert the hash to a string, and we also want RAW SHA512_Final(sha512sum, &ctx); memcpy(output, sha512sum, output_length); // adapted from SHA512_End if(!leaveRaw) { for (j = 0; j < output_length; j++) { *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } case 101: { /* md5 file case */ int j; md5_context ctx; output_length = 16; unsigned char buf[1024]; unsigned char md5sum[16]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); md5_starts( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; md5_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) md5_update( &ctx, buf, nChar ); } fclose(fp); md5_finish( &ctx, md5sum ); memcpy(output, md5sum, 16); if (!leaveRaw) for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 102: { /* sha1 file case */ int j; sha1_context ctx; output_length = 20; unsigned char buf[1024]; unsigned char sha1sum[20]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); sha1_starts ( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha1_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha1_update( &ctx, buf, nChar ); } fclose(fp); sha1_finish ( &ctx, sha1sum ); memcpy(output, sha1sum, 20); if(!leaveRaw) for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 103: { /* crc32 file case */ unsigned char buf[1024]; unsigned long val; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); val = digest_crc32(0L, 0, 0); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; val = digest_crc32(val , buf, (unsigned) nChar); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) val = digest_crc32(val , buf, (unsigned) nChar); } fclose(fp); sprintf(output, "%2.2x", (unsigned int) val); break; } case 104: { /* sha256 file case */ int j; sha256_context ctx; output_length = 32; unsigned char buf[1024]; unsigned char sha256sum[32]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); sha256_starts ( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha256_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha256_update( &ctx, buf, nChar ); } fclose(fp); sha256_finish ( &ctx, sha256sum ); memcpy(output, sha256sum, 32); if(!leaveRaw) for( j = 0; j < 32; j++ ) sprintf( output + j * 2, "%02x", sha256sum[j] ); break; } case 105: { /* sha2-512 file case */ int j; SHA512_CTX ctx; output_length = SHA512_DIGEST_LENGTH; uint8_t sha512sum[output_length], *d = sha512sum; unsigned char buf[1024]; if (!(fp = fopen(txt,"rb"))) { error("Cannot open input file: %s", txt); return(NULL); } if (skip > 0) fseek(fp, skip, SEEK_SET); SHA512_Init(&ctx); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; SHA512_Update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) SHA512_Update( &ctx, buf, nChar ); } fclose(fp); // Calling SHA512_Final, because SHA512_End will already // convert the hash to a string, and we also want RAW SHA512_Final(sha512sum, &ctx); memcpy(output, sha512sum, output_length); // adapted from SHA512_End if(!leaveRaw) { for (j = 0; j < output_length; j++) { *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } default: { error("Unsupported algorithm code"); return(NULL); } } if (leaveRaw && output_length > 0) { PROTECT(result=allocVector(RAWSXP, output_length)); memcpy(RAW(result), output, output_length); } else { PROTECT(result=allocVector(STRSXP, 1)); SET_STRING_ELT(result, 0, mkChar(output)); } UNPROTECT(1); return result; }
sess_t sess_start(sm_t sm, jid_t jid) { pool_t p; user_t user; sess_t sess, scan; sha1_state_t sha1; unsigned char hash[20]; int replaced = 0; log_debug(ZONE, "session requested for %s", jid_full(jid)); /* check whether it is to serviced domain */ if(xhash_get(sm->hosts, jid->domain) == NULL) { log_write(sm->log, LOG_ERR, "request to start session in non-serviced domain: jid=%s", jid_full(jid)); return NULL; } /* get user data for this guy */ user = user_load(sm, jid); /* unknown user */ if(user == NULL) { if(config_get(sm->config, "user.auto-create") == NULL) { log_write(sm->log, LOG_NOTICE, "user not found and user.auto-create not enabled, can't start session: jid=%s", jid_full(jid)); return NULL; } log_debug(ZONE, "auto-creating user %s", jid_user(jid)); if(user_create(sm, jid) != 0) return NULL; user = user_load(sm, jid); if(user == NULL) { log_write(sm->log, LOG_NOTICE, "couldn't load user, can't start session: jid=%s", jid_full(jid)); return NULL; } } /* kill their old session if they have one */ for(scan = user->sessions; scan != NULL; scan = scan->next) if(jid_compare_full(scan->jid, jid) == 0) { log_debug(ZONE, "replacing session %s (%s)", jid_full(jid), scan->c2s_id); /* !!! this "replaced" stuff is a hack - its really a subaction of "ended". * hurrah, another control protocol rewrite is needed :( */ sm_c2s_action(scan, "replaced", NULL); _sess_end_guts(scan); pool_free(scan->p); replaced = 1; break; } /* make a new session */ p = pool_new(); sess = (sess_t) pmalloco(p, sizeof(struct sess_st)); sess->p = p; /* fill it out */ sess->pri = 0; sess->user = user; sess->jid = jid_dup(jid); pool_cleanup(sess->p, (void (*))(void *) jid_free, sess->jid); /* a place for modules to store stuff */ sess->module_data = (void **) pmalloco(sess->p, sizeof(void *) * sess->user->sm->mm->nindex); /* add it to the list */ sess->next = user->sessions; user->sessions = sess; /* who c2s should address things to */ sha1_init(&sha1); datetime_out(time(NULL), dt_DATETIME, sess->sm_id, 41); sha1_append(&sha1, sess->sm_id, strlen(sess->sm_id)); sha1_append(&sha1, jid_full(sess->jid), strlen(jid_full(sess->jid))); sha1_finish(&sha1, hash); hex_from_raw(hash, 20, sess->sm_id); log_debug(ZONE, "smid is %s", sess->sm_id); /* remember it */ xhash_put(sm->sessions, sess->sm_id, sess); /* inform the modules */ /* !!! catch the return value - if its 1, don't let them in */ mm_sess_start(sm->mm, sess); if(replaced) log_write(sm->log, LOG_NOTICE, "session replaced: jid=%s", jid_full(sess->jid)); else log_write(sm->log, LOG_NOTICE, "session started: jid=%s", jid_full(sess->jid)); return sess; }
int ssl_derive_keys(ssl_context * ssl) { size_t i; md5_context md5; sha1_context sha1; uint8_t tmp[64]; uint8_t padding[16]; uint8_t sha1sum[20]; uint8_t keyblk[256]; uint8_t *key1; uint8_t *key2; SSL_DEBUG_MSG(2, ("=> derive keys")); /* * SSLv3: * master = * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) * * TLSv1: * master = PRF( premaster, "master secret", randbytes )[0..47] */ if (ssl->resume == 0) { size_t len = ssl->pmslen; SSL_DEBUG_BUF(3, "premaster secret", ssl->premaster, len); if (ssl->minor_ver == SSL_MINOR_VERSION_0) { for (i = 0; i < 3; i++) { memset(padding, 'A' + i, 1 + i); sha1_starts(&sha1); sha1_update(&sha1, padding, 1 + i); sha1_update(&sha1, ssl->premaster, len); sha1_update(&sha1, ssl->randbytes, 64); sha1_finish(&sha1, sha1sum); md5_starts(&md5); md5_update(&md5, ssl->premaster, len); md5_update(&md5, sha1sum, 20); md5_finish(&md5, ssl->session->master + i * 16); } } else tls1_prf(ssl->premaster, len, "master secret", ssl->randbytes, 64, ssl->session->master, 48); memset(ssl->premaster, 0, sizeof(ssl->premaster)); } else SSL_DEBUG_MSG(3, ("no premaster (session resumed)")); /* * Swap the client and server random values. */ memcpy(tmp, ssl->randbytes, 64); memcpy(ssl->randbytes, tmp + 32, 32); memcpy(ssl->randbytes + 32, tmp, 32); memset(tmp, 0, sizeof(tmp)); /* * SSLv3: * key block = * MD5( master + SHA1( 'A' + master + randbytes ) ) + * MD5( master + SHA1( 'BB' + master + randbytes ) ) + * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + * ... * * TLSv1: * key block = PRF( master, "key expansion", randbytes ) */ if (ssl->minor_ver == SSL_MINOR_VERSION_0) { for (i = 0; i < 16; i++) { memset(padding, 'A' + i, 1 + i); sha1_starts(&sha1); sha1_update(&sha1, padding, 1 + i); sha1_update(&sha1, ssl->session->master, 48); sha1_update(&sha1, ssl->randbytes, 64); sha1_finish(&sha1, sha1sum); md5_starts(&md5); md5_update(&md5, ssl->session->master, 48); md5_update(&md5, sha1sum, 20); md5_finish(&md5, keyblk + i * 16); } memset(&md5, 0, sizeof(md5)); memset(&sha1, 0, sizeof(sha1)); memset(padding, 0, sizeof(padding)); memset(sha1sum, 0, sizeof(sha1sum)); } else tls1_prf(ssl->session->master, 48, "key expansion", ssl->randbytes, 64, keyblk, 256); SSL_DEBUG_MSG(3, ("cipher = %s", ssl_get_cipher(ssl))); SSL_DEBUG_BUF(3, "master secret", ssl->session->master, 48); SSL_DEBUG_BUF(4, "random bytes", ssl->randbytes, 64); SSL_DEBUG_BUF(4, "key block", keyblk, 256); memset(ssl->randbytes, 0, sizeof(ssl->randbytes)); /* * Determine the appropriate key, IV and MAC length. */ switch (ssl->session->cipher) { #if defined(TROPICSSL_ARC4) case TLS_RSA_WITH_RC4_128_MD5: ssl->keylen = 16; ssl->minlen = 16; ssl->ivlen = 0; ssl->maclen = 16; break; case TLS_RSA_WITH_RC4_128_SHA: ssl->keylen = 16; ssl->minlen = 20; ssl->ivlen = 0; ssl->maclen = 20; break; #endif #if defined(TROPICSSL_DES) case TLS_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: ssl->keylen = 24; ssl->minlen = 24; ssl->ivlen = 8; ssl->maclen = 20; break; #endif #if defined(TROPICSSL_AES) case TLS_RSA_WITH_AES_128_CBC_SHA: ssl->keylen = 16; ssl->minlen = 32; ssl->ivlen = 16; ssl->maclen = 20; break; case TLS_RSA_WITH_AES_256_CBC_SHA: case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: ssl->keylen = 32; ssl->minlen = 32; ssl->ivlen = 16; ssl->maclen = 20; break; #endif #if defined(TROPICSSL_CAMELLIA) case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: ssl->keylen = 16; ssl->minlen = 32; ssl->ivlen = 16; ssl->maclen = 20; break; case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: ssl->keylen = 32; ssl->minlen = 32; ssl->ivlen = 16; ssl->maclen = 20; break; #endif default: SSL_DEBUG_MSG(1, ("cipher %s is not available", ssl_get_cipher(ssl))); return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); } SSL_DEBUG_MSG(3, ("keylen: %d, minlen: %d, ivlen: %d, maclen: %d", ssl->keylen, ssl->minlen, ssl->ivlen, ssl->maclen)); /* * Finally setup the cipher contexts, IVs and MAC secrets. */ if (ssl->endpoint == SSL_IS_CLIENT) { key1 = keyblk + ssl->maclen * 2; key2 = keyblk + ssl->maclen * 2 + ssl->keylen; memcpy(ssl->mac_enc, keyblk, ssl->maclen); memcpy(ssl->mac_dec, keyblk + ssl->maclen, ssl->maclen); memcpy(ssl->iv_enc, key2 + ssl->keylen, ssl->ivlen); memcpy(ssl->iv_dec, key2 + ssl->keylen + ssl->ivlen, ssl->ivlen); } else { key1 = keyblk + ssl->maclen * 2 + ssl->keylen; key2 = keyblk + ssl->maclen * 2; memcpy(ssl->mac_dec, keyblk, ssl->maclen); memcpy(ssl->mac_enc, keyblk + ssl->maclen, ssl->maclen); memcpy(ssl->iv_dec, key1 + ssl->keylen, ssl->ivlen); memcpy(ssl->iv_enc, key1 + ssl->keylen + ssl->ivlen, ssl->ivlen); } switch (ssl->session->cipher) { #if defined(TROPICSSL_ARC4) case TLS_RSA_WITH_RC4_128_MD5: case TLS_RSA_WITH_RC4_128_SHA: arc4_setup((arc4_context *) ssl->ctx_enc, key1, ssl->keylen); arc4_setup((arc4_context *) ssl->ctx_dec, key2, ssl->keylen); break; #endif #if defined(TROPICSSL_DES) case TLS_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: des3_set3key_enc((des3_context *) ssl->ctx_enc, key1); des3_set3key_dec((des3_context *) ssl->ctx_dec, key2); break; #endif #if defined(TROPICSSL_AES) case TLS_RSA_WITH_AES_128_CBC_SHA: aes_setkey_enc((aes_context *) ssl->ctx_enc, key1, 128); aes_setkey_dec((aes_context *) ssl->ctx_dec, key2, 128); break; case TLS_RSA_WITH_AES_256_CBC_SHA: case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: aes_setkey_enc((aes_context *) ssl->ctx_enc, key1, 256); aes_setkey_dec((aes_context *) ssl->ctx_dec, key2, 256); break; #endif #if defined(TROPICSSL_CAMELLIA) case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: camellia_setkey_enc((camellia_context *) ssl->ctx_enc, key1, 128); camellia_setkey_dec((camellia_context *) ssl->ctx_dec, key2, 128); break; case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: camellia_setkey_enc((camellia_context *) ssl->ctx_enc, key1, 256); camellia_setkey_dec((camellia_context *) ssl->ctx_dec, key2, 256); break; #endif default: return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); } memset(keyblk, 0, sizeof(keyblk)); SSL_DEBUG_MSG(2, ("<= derive keys")); return (0); }
void crypto_sha1_final(CryptoSha1 sha1, uint8 * out_data) { sha1_finish(&sha1->ctx, out_data); xfree(sha1); }
void CServer::RunOTThread() { cout << "\not thread started\n" << flush; // IKNP-first step: receiver of Naor-Pinkas ZZ& p = CConfig::GetInstance()->GetPrime(); ZZ q = p/2 - 1; ZZ& g = CConfig::GetInstance()->GetGenerator(); // NP receiver: receive Cs int nBufSize = NUM_EXECS_NAOR_PINKAS * FIELD_SIZE_IN_BYTES; BYTE* pBuf = new BYTE[nBufSize]; m_sockOT.Receive(pBuf, nBufSize); ZZ* pC = new ZZ[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufIdx = pBuf; for(int i=0, idx=0; i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(pC[i], pBufIdx, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; #ifdef _DEBUG cout << "pC[" << i <<"]: " << pC[i] << endl; #endif } // compute pk0, pk1 CBitVector rnd; rnd.Create(NUM_EXECS_NAOR_PINKAS*FIELD_SIZE_IN_BITS, m_aSeed, m_nCounter); BYTE* pBufRnd = rnd.GetArr(); ZZ* pK = new ZZ[NUM_EXECS_NAOR_PINKAS]; ZZ ztmp; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(ztmp, pBufRnd, FIELD_SIZE_IN_BYTES); pBufRnd += FIELD_SIZE_IN_BYTES; rem(pK[i], ztmp, q); } pBufIdx = pBuf; ZZ pk0, pk1; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { // compute pk0, pk1 if( !m_S.GetBit(i) ) { PowerMod(pk0, g, pK[i], p); } else { PowerMod(pk1, g, pK[i], p); //pk0 = pC[i]/pk1; InvMod(ztmp, pk1, p); MulMod(pk0, pC[i], ztmp, p); } #ifdef _DEBUG cout << "pk0[" << i << "]: " << pk0 << endl; #endif // put pk0 BytesFromZZ(pBufIdx, pk0, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; } m_sockOT.Send(pBuf, nBufSize); delete [] pC; delete [] pBuf; if( m_bStop ) return; // NP receiver: get the g^r0, Enc(M0), g^r2, Enc(M1) int nInputStart = m_pCircuit->GetInputStart(ID_CLIENT); int nInputEnd = m_pCircuit->GetInputEnd(ID_CLIENT); int nMsgSize = (nInputEnd-nInputStart)/SHA1_BITS + 1; // in sha1 scale int nMsginOT = FIELD_SIZE_IN_BYTES + nMsgSize*SHA1_BYTES; int nBufSize2 = NUM_EXECS_NAOR_PINKAS * nMsginOT * 2; BYTE* pBuf2 = new BYTE[nBufSize2]; m_sockOT.Receive(pBuf2, nBufSize2); ZZ w; ZZ key; BYTE tmp[FIELD_SIZE_IN_BYTES]; sha1_context sha; SHA_BUFFER buf_key; BYTE** ppMat = new BYTE*[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufToRead; BYTE* pBufMatIdx; pBufIdx = pBuf2; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ppMat[i] = new BYTE[nMsgSize*SHA1_BYTES]; if( !m_S.GetBit(i)) { pBufToRead = pBufIdx; pBufIdx += nMsginOT + nMsginOT; } else { pBufIdx += nMsginOT; pBufToRead = pBufIdx; pBufIdx += nMsginOT; } ZZFromBytes(w, pBufToRead, FIELD_SIZE_IN_BYTES); pBufToRead += FIELD_SIZE_IN_BYTES; PowerMod(key, w, pK[i], p); BytesFromZZ(tmp, key, FIELD_SIZE_IN_BYTES); sha1_starts(&sha); sha1_update(&sha, tmp, FIELD_SIZE_IN_BYTES); sha1_finish(&sha, (BYTE*) &buf_key); pBufMatIdx=ppMat[i]; for(int j=0; j<nMsgSize; j++) { sha1_starts(&sha); sha1_update(&sha, (BYTE*) &buf_key, sizeof(buf_key)); sha1_update(&sha, (BYTE*) &j, sizeof(int)); sha1_finish(&sha, tmp); for(int x=0; x<SHA1_BYTES; x++, pBufMatIdx++, pBufToRead++ ) { *(pBufMatIdx) = *(pBufToRead) ^ tmp[x]; } } } delete [] pK; if( m_bStop ) return; // IKNP-second step: send the keys for client inputs int nInputSize = nInputEnd - nInputStart + 1; KEY* pKeys = new KEY[nInputSize*2]; YAO_WIRE* wire; KEY* wirekey; CBitVector qj; qj.Create(NUM_EXECS_NAOR_PINKAS); int j=0; // 0-starting index KEY* pKeyIdx = pKeys; for(int i=nInputStart; !m_bStop && i<=nInputEnd; i++,j++) { while( m_nGatesDone < i ) { SleepMiliSec(100); } // compute qj for(int r=0; r<NUM_EXECS_NAOR_PINKAS; r++) { qj.SetBit( r, ppMat[r][j/8] & bitmask[j & 0x7] ); } // compute hash sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); // y0 wire = m_pYaoWires+i; wirekey = wire->keys + wire->b; XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; // compute qj xor s for(int x=0; x<NUM_EXECS_NAOR_PINKAS/8; x++ ) qj.GetArr()[x] ^= m_S.GetByte(x); /* #ifdef _DEBUG cout << "qj xor s = "; for(int z=0; z<NUM_EXECS_NAOR_PINKAS; z++) cout << (int) qj.GetBit(z); cout << endl; #endif */ // y1 sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); wirekey = wire->keys + (wire->b^1); XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; } m_sockOT.Send( pKeys, nInputSize*sizeof(KEY)*2); // clean-up delete [] pBuf2; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { delete [] ppMat[i]; } delete [] ppMat; delete [] pKeys; cout << "\not thread ended \n" << flush; }
BOOL CServer::Init() { // circuit CConfig* cf = CConfig::GetInstance(); int nInputs = cf->GetNumInputs(); if( !cf->GetCircFileName().empty() ) { m_pCircuit = LOAD_CIRCUIT_BIN(cf->GetCircFileName().c_str()); if(!m_pCircuit) { cout << "failure in loading circuit " << cf->GetCircFileName() << endl; return FALSE; } } else { m_pCircuit = CREATE_CIRCUIT(cf->GetNumParties(), cf->GetCircCreateName(), cf->GetCircCreateParams() ); } m_pGates = m_pCircuit->Gates(); m_nNumGates = m_pCircuit->GetNumGates(); // bind the constant m_pGates[0].val = 0; m_pGates[1].val = 1; // bind the input int nBits = m_pCircuit->GetNumVBits(ID_SERVER); int nStart = m_pCircuit->GetInputStart(ID_SERVER); int nEnd = m_pCircuit->GetInputEnd(ID_SERVER); vector<int> vIn; CConfig::GetInstance()->GetInput(vIn); //cout << "s=" << nStart << " e= " << nEnd << endl; int j=nStart; for( int i=0; i<nInputs && j <=nEnd; i++ ) { for(int k=0; k<nBits && j<=nEnd; k++ ) { int mask = (1 << k ); m_pGates[j++].val = !!(vIn[i] & mask); } } #ifdef _DEBUG if( nInputs == 10 ) { j = nStart; for( int i=0; i<nInputs; i++ ) { cout << "id[" << i << "]: "; for(int k=0; k<nBits; k++ ) { cout << (int) m_pGates[j].val; j++; } cout << endl; } assert(j == nEnd+1); int i= m_pCircuit->GetInputStart(ID_CLIENT); m_pGates[i++].val = 0; m_pGates[i++].val = 0; m_pGates[i++].val = 1; m_pGates[i++].val = 0; m_pGates[i++].val = 0; m_pGates[i++].val = 1; m_pGates[i++].val = 1; m_pGates[i++].val = 0; m_pGates[i++].val = 0; m_pGates[i++].val = 0; m_pCircuit->Evaluate(); } #endif // yao m_pYaoWires = new YAO_WIRE[m_nNumGates]; m_pYaoGates = new YAO_GARBLED_GATE[m_nNumGates - m_pCircuit->GetGateStart()]; m_vOutGates.reserve(1024); m_nGatesDone = -1; m_nWiresDone = -1; // randomness sha1_context sha; sha1_starts(&sha); sha1_update(&sha, (BYTE*) cf->GetSeed().c_str(), cf->GetSeed().length()); sha1_finish(&sha, m_aSeed); m_nCounter = 1; // batch parameters m_nGateBatch = NUM_GATE_BATCH; m_nKeyBatch = NUM_KEY_BATCH; // IKNP m_S.Create(NUM_EXECS_NAOR_PINKAS, m_aSeed, m_nCounter ); m_bStop = FALSE; return TRUE; }
/* spl_image defined in spl.c */ void spl_sboot_extend(void) { uint8_t csum[20]; uint8_t out_digest[20]; uint8_t image_buffer[SBOOT_SPL_READ_SIZE]; SHA1_CTX ctx; #ifdef CONFIG_SBOOT_TIMING uint32_t timer_begin = get_timer_masked(); #endif sha1_starts(&ctx); /* Only support MMC/FAT */ #if defined(CONFIG_SPL_MMC_SUPPORT) && defined(CONFIG_SPL_FAT_SUPPORT) /* Todo: add a configuration option to limit the memory read length. * This will allow us to SHA1 in blocks. * Todo: add a configuration option to use the TPM's SHA1 for extreme * memory contention scenarios. */ sha1_update(&ctx, (unsigned char *) spl_image.load_addr, spl_image.size); #else #warning "Warning: sboot does not support the U-Boot storage configuration." #endif sha1_finish(&ctx, csum); if (sboot_extend(SBOOT_PCR_UBOOT, csum, out_digest) != SBOOT_SUCCESS) { puts("SPL: (sboot) error while measuring U-Boot\n"); goto finished; } sha1_starts(&ctx); /* Extend EEPROM, support I2C only */ #ifdef CONFIG_ENV_EEPROM_IS_ON_I2C /* for (i = 0; i * SBOOT_SPL_READ_SIZE < CONFIG_SYS_I2C_EEPROM_SIZE; ++i) { memset(image_buffer, 0, SBOOT_SPL_READ_SIZE); if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, image_buffer, SBOOT_SPL_READ_SIZE)) { puts("SPL: (sboot) could not read the EEPROM\n"); return; } sha1_update(&ctx, image_buffer, SBOOT_SPL_READ_SIZE); }*/ debug("SPL: (sboot) measuring EEPROM\n"); i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, image_buffer, CONFIG_SYS_I2C_EEPROM_SIZE); sha1_update(&ctx, image_buffer, CONFIG_SYS_I2C_EEPROM_SIZE); debug("SPL: (sboot) finished\n"); #else #warning "Warning: sboot does not support the ENV storage configuration." #endif sha1_finish(&ctx, csum); if (sboot_extend(SBOOT_PCR_CHIPSET_CONFIG, csum, out_digest) != SBOOT_SUCCESS) { puts("SPL: (sboot) error while measuring chipset config\n"); goto finished; } finished: #ifdef CONFIG_SBOOT_TIMING report_time("extend", get_timer_masked() - timer_begin); #endif return; }
static char * digest_string( char *txt, int algo, int length, char *output) { FILE *fp=0; error_message = NULL; int nChar = strlen(txt); if (length>=0 && length<nChar) nChar = length; switch (algo) { case 1: { /* md5 case */ md5_context ctx; unsigned char md5sum[16]; int j; md5_starts( &ctx ); md5_update( &ctx, (uint8 *) txt, nChar); md5_finish( &ctx, md5sum ); for(j = 0; j < 16; j++) { sprintf(output + j * 2, "%02x", md5sum[j]); } break; } case 2: { /* sha1 case */ int j; sha1_context ctx; unsigned char sha1sum[20]; sha1_starts( &ctx ); sha1_update( &ctx, (uint8 *) txt, nChar); sha1_finish( &ctx, sha1sum ); for( j = 0; j < 20; j++ ) { sprintf( output + j * 2, "%02x", sha1sum[j] ); } break; } case 3: { /* crc32 case */ unsigned long val, l; l = nChar; val = digest_crc32(0L, 0, 0); val = digest_crc32(val, (unsigned char*) txt, (unsigned) l); sprintf(output, "%2.2x", (unsigned int) val); break; } case 101: { /* md5 file case */ int j; md5_context ctx; unsigned char buf[1024]; unsigned char md5sum[16]; if (!(fp = fopen(txt,"rb"))) { error_message = (strcat("Can not open input file: ", txt)); return (char *)NULL; } md5_starts( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; md5_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) md5_update( &ctx, buf, nChar ); } fclose(fp); md5_finish( &ctx, md5sum ); for(j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 102: { /* sha1 file case */ int j; sha1_context ctx; unsigned char buf[1024]; unsigned char sha1sum[20]; if (!(fp = fopen(txt,"rb"))) { error_message = (strcat("Can not open input file: ", txt)); return (char *)NULL; } sha1_starts ( &ctx ); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha1_update( &ctx, buf, nChar ); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha1_update( &ctx, buf, nChar ); } fclose(fp); sha1_finish ( &ctx, sha1sum ); for( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 103: { /* crc32 file case */ unsigned char buf[1024]; unsigned long val; if (!(fp = fopen(txt,"rb"))) { error_message = (strcat("Can not open input file: ", txt)); return (char *)NULL; } val = digest_crc32(0L, 0, 0); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; val = digest_crc32(val , buf, (unsigned) nChar); length -= nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) val = digest_crc32(val , buf, (unsigned) nChar); } fclose(fp); sprintf(output, "%2.2x", (unsigned int) val); break; } default: { error_message = ("Unsupported algorithm code"); return (char *)NULL; } } return output; }
static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx) { sha1_finish(ctx, digest); }
int main(void) { socklen_t fromlen; int len, n, server_socket, fd_log; unsigned long int nb_written; struct sockaddr_in client_addr; struct sockaddr_in server_addr; unsigned char logbuf[MAX_LOG_PKT_SZ]; unsigned char sha1sum[SHA1_SZ]; sha1_context sha1; create_log(&fd_log); nb_written = 0; /* start the UDP listening server */ if ((server_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { server_err("Socket creation failed: %d\n", errno); exit(1); } n = 1; if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (void *) &n, sizeof ( n)) < 0) { server_err("Set socket options failed: %d\n", errno); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SHELL_LOG_SERVER_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof ( server_addr)) < 0) { server_err("Bind socket failed: %d\n", errno); exit(1); } if (fork() != 0) exit(0); setsid(); while (1) { fromlen = sizeof (client_addr); if ((len = recvfrom(server_socket, &logbuf[IP_SZ + LENGTH_SZ], BUF_SZ, 0, (struct sockaddr *) &client_addr, &fromlen)) < MIN_TRANSFER_PKT_SZ) { // sleep(1); continue; } server_dbg("Received packet: %d\n", len); sha1_starts(&sha1); sha1_update(&sha1, logbuf + IP_SZ + LENGTH_SZ + RC4_SZ, len - RC4_SZ - SHA1_SZ); sha1_finish(&sha1, sha1sum); if (memcmp(logbuf + IP_SZ + LENGTH_SZ + len - SHA1_SZ, sha1sum, SHA1_SZ) != 0) { server_err("SHA-1 checksum verification failed\n"); continue; } memcpy(logbuf, &client_addr.sin_addr.s_addr, IP_SZ); memcpy(&logbuf[IP_SZ], &len, LENGTH_SZ); server_dbg("From : %d.%d.%d.%d\n", (client_addr.sin_addr.s_addr) & 0xFF, (client_addr.sin_addr.s_addr >> 8) & 0xFF, (client_addr.sin_addr.s_addr >> 16) & 0xFF, (client_addr.sin_addr.s_addr >> 24) & 0xFF ); write(fd_log, logbuf, IP_SZ + LENGTH_SZ + len); nb_written += (IP_SZ + LENGTH_SZ + len); if (nb_written > MAX_LOG_SIZE) { nb_written = 0; close(fd_log); create_log(&fd_log); } } return ( 0); }
const wxString wxSHA1::GetDigest(bool mainthread) { if (m_isfile) { if(m_bCalculatedDigest) { const wxString szRetVal = m_pszDigestString; return szRetVal; } else if(!m_file.FileExists()) { return wxEmptyString; } else { sha1_context sha1Context; sha1_starts(&sha1Context); wxFile sha1file(m_file.GetFullPath(), wxFile::read); unsigned char buffer[16384]; unsigned int i = 1; while (i >0) { i = sha1file.Read(buffer,16384); sha1_update(&sha1Context, buffer, (unsigned) i); if (mainthread) wxYield(); } sha1_finish(&sha1Context,m_arrDigest); wxString szRetVal; unsigned int j=0; for (i = 0; i < sizeof m_arrDigest; i++) { szRetVal << wxString::Format(wxT("%02X"),m_arrDigest[i]); m_pszDigestString[j] = szRetVal.GetChar(j); m_pszDigestString[j+1] = szRetVal.GetChar(j+1); j+=2; } return szRetVal; } } else { if(m_bCalculatedDigest) { const wxString szRetVal = m_pszDigestString; return szRetVal; } else if(m_szText.IsEmpty()) { return wxEmptyString; } else { sha1_context sha1Context; sha1_starts(&sha1Context); char *text = new char[m_szText.Len()+1]; unsigned int i; for (i=0; i < (m_szText.Len());i++) text[i] = m_szText.GetChar(i); text[i] = '\0'; sha1_update(&sha1Context, (unsigned char*)(text), strlen(text)); sha1_finish(&sha1Context,m_arrDigest); wxString szRetVal; unsigned int j=0; for (i = 0; i < sizeof m_arrDigest; i++) { szRetVal << wxString::Format(wxT("%02X"),m_arrDigest[i]); m_pszDigestString[j] = szRetVal.GetChar(j); m_pszDigestString[j+1] = szRetVal.GetChar(j+1); j+=2; } return szRetVal; } } }
static void sha1_finish_wrap( void *ctx, unsigned char *output ) { sha1_finish( (sha1_context *) ctx, output ); }
/* void generate_mac(const char *data, const char *key, unsigned char *mac) { unsigned int h[5]; sha1_init(h); sha1_update(key, h); sha1_update(data); sha1_finish(mac); } */ int main(int argc, char *argv[]) { unsigned char mac[20]; char buff[128]; unsigned char tamp[2048]; const char *data = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"; init_key(); generate_mac(SHA1, data, strlen(data), secret_key, secret_key_len, mac); hexencode(mac, 20, buff); buff[40] = '\0'; printf("digest: %s\n", buff); printf("mac valid: %d\n", validate_mac(SHA1, data, strlen(data), secret_key, secret_key_len, mac)); strcpy(tamp, data); strcat(tamp, ";admin=true"); printf("tampered msg mac valid: %d\n", validate_mac(SHA1, tamp, strlen(tamp), secret_key, secret_key_len, mac)); // now try to bruteforce a valid message by continuing the existing mac. // // valid mac is based on sha1(key || msg) which is generated by sha1_update(key || msg || padding0) // we want sha1(key || msg || padding0 || tampering || padding1) to be valid, // for that we need to guess key length and append tampering and continue // the sha1 hash function over padding and tampering. // padding = | 0x80 0000 ... 0000 LEN | where // // tampered mac unsigned char tampmac[20]; int msglen = strlen(data); int keylen = 0; // start with a zero length key int valid; do { // the sha1 state we will continue on // // h[5] // | // key || msg || padding0 // unsigned int h[5]; int i; for(i = 0; i < 5; i++) { h[i] = (mac[i*4] << 24) | (mac[i*4+1] << 16) | (mac[i*4+2] << 8) | mac[i*4+3]; // printf("h[%d] = %08X\n", i, h[i]); } strcpy(tamp, ";admin=true"); int key_data_padding0_len = ((keylen + msglen + 9) + 64 - (keylen + msglen + 9) % 64); int tamp_len = strlen(tamp); // the length of the tampered message, that is msglen + keylen + padding + tamp // calculate tampered mac // the sha1 state we will continue on // // h[5] ----> tamp_mac // | | // key || msg || padding0 || tamp || padding1 // sha1_finish(tamp, key_data_padding0_len + tamp_len, h, tampmac); //printf("tampered mac:\n"); //hexdump(tampmac, 20); // generate tampered the message, that is, original message + padding0 + tampered data strcpy(tamp, data); // append padding0 after original message // // length of padding0 is (key+msg+9+64) - (key+msg+9+64) % 64 unsigned char *p = tamp+strlen(tamp); *p++ = 0x80; // nullpadd until 8 bytes from block boundary while( (keylen + (p - (unsigned char *)tamp) ) % 64 != 56) { *p++ = 0; } // first 32 bits of 64 bit length indicator is zero *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; unsigned int bits = 8*(msglen + keylen); // append the 32 bit length field *p++ = bits >> 24; *p++ = bits >> 16; *p++ = bits >> 8; *p++ = bits & 0xff; // append tampering strcpy(p, ";admin=true"); p += strlen(p); int tampered_msg_len = p - tamp; //printf("Validate mac using length: %d\n", tampered_msg_len); //hexdump(tamp, tampered_msg_len); valid = validate_mac(SHA1, tamp, tampered_msg_len, secret_key, secret_key_len, tampmac); if(!valid) { keylen++; printf("Message not accepted, try larger keylength %d\n", keylen); } else { printf("tampered message accepted, guessed keylength: %d\n", keylen); } } while(!valid && keylen < 256); if(!valid) { printf("Failed to get tampered message accepted\n"); } }