static void SHA512_File(FILE *file, unsigned char **output, int *outlength) { *output = new unsigned char[SHA512_DIGEST_LENGTH]; *outlength = SHA512_DIGEST_LENGTH; SHA512_CTX c; int i; unsigned char buf[SHA384_FILE_BUFFER_SIZE]; SHA512_Init(&c); for (;;) { i = fread(buf,1,SHA512_FILE_BUFFER_SIZE,file); if(i <= 0) break; SHA512_Update(&c,buf,(unsigned long)i); } SHA512_Final(*output, &c); }
static int chk_sha512( const struct berval *scheme, /* Scheme of hashed reference password */ const struct berval *passwd, /* Hashed reference password to check against */ const struct berval *cred, /* user-supplied password to check */ const char **text ) { SHA512_CTX SHAcontext; unsigned char SHAdigest[SHA512_DIGEST_LENGTH]; int rc; unsigned char *orig_pass = NULL; size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); /* safety check */ if (decode_len < sizeof(SHAdigest)) { return LUTIL_PASSWD_ERR; } /* base64 un-encode password */ orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); if( rc != sizeof(SHAdigest) ) { ber_memfree(orig_pass); return LUTIL_PASSWD_ERR; } /* hash credentials with salt */ SHA512_Init(&SHAcontext); SHA512_Update(&SHAcontext, (const unsigned char *) cred->bv_val, cred->bv_len); SHA512_Final(SHAdigest, &SHAcontext); /* compare */ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); #ifdef SLAPD_SHA2_DEBUG chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); #endif ber_memfree(orig_pass); return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; }
static int hash_sha512( const struct berval *scheme, const struct berval *passwd, struct berval *hash, const char **text ) { SHA512_CTX ct; unsigned char hash512[SHA512_DIGEST_LENGTH]; SHA512_Init(&ct); SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); SHA512_Final(hash512, &ct); struct berval digest; digest.bv_val = (char *) hash512; digest.bv_len = sizeof(hash512); return pw_string64(scheme, &digest, hash, NULL); }
/* -- Blinding ------------------------------------------------------------- // // Blinding is a measure to protect against side channel attacks. // Blinding randomizes the scalar multiplier. // // Instead of calculating a*P, calculate (a+b mod BPO)*P + B // // Where b = random blinding and B = -b*P // // ------------------------------------------------------------------------- */ void *ed25519_Blinding_Init( void *context, /* IO: null or ptr blinding context */ const unsigned char *seed, /* IN: [size bytes] random blinding seed */ size_t size) /* IN: size of blinding seed */ { struct { Ext_POINT T; U_WORD t[K_WORDS]; SHA512_CTX H; U8 digest[SHA512_DIGEST_LENGTH]; } d; EDP_BLINDING_CTX *ctx = (EDP_BLINDING_CTX*)context; if (ctx == 0) { ctx = (EDP_BLINDING_CTX*)mem_alloc(sizeof(EDP_BLINDING_CTX)); if (ctx == 0) return 0; } /* Use edp_custom_blinding to protect generation of the new blinder */ SHA512_Init(&d.H); SHA512_Update(&d.H, edp_custom_blinding.zr, 32); SHA512_Update(&d.H, seed, size); SHA512_Final(d.digest, &d.H); ecp_BytesToWords(ctx->zr, d.digest+32); ecp_BytesToWords(d.t, d.digest); eco_Mod(d.t); ecp_Sub(ctx->bl, _w_BPO, d.t); eco_AddReduce(d.t, d.t, edp_custom_blinding.bl); edp_BasePointMult(&d.T, d.t, edp_custom_blinding.zr); edp_AddPoint(&d.T, &d.T, &edp_custom_blinding.BP); edp_ExtPoint2PE(&ctx->BP, &d.T); /* clear potentially sensitive data */ mem_clear (&d, sizeof(d)); return ctx; }
int sha_file(int md_alg, const char *filename, unsigned char *md) { FILE *inFile; SHA256_CTX shaContext; SHA512_CTX sha512Context; int bytes; unsigned char data[BUFFER_SIZE]; if ((filename == NULL) || (md == NULL)) { ERROR("%s(): NULL argument\n", __FUNCTION__); return 0; } inFile = fopen(filename, "rb"); if (inFile == NULL) { ERROR("Cannot read %s\n", filename); return 0; } if (md_alg == HASH_ALG_SHA384) { SHA384_Init(&sha512Context); while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { SHA384_Update(&sha512Context, data, bytes); } SHA384_Final(md, &sha512Context); } else if (md_alg == HASH_ALG_SHA512) { SHA512_Init(&sha512Context); while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { SHA512_Update(&sha512Context, data, bytes); } SHA512_Final(md, &sha512Context); } else { SHA256_Init(&shaContext); while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { SHA256_Update(&shaContext, data, bytes); } SHA256_Final(md, &shaContext); } fclose(inFile); return 1; }
static int32_t sha512(char *in, char **out) { SHA512_CTX ctx; uint32_t i = 0; int32_t rtrn = 0; unsigned char hash[SHA512_DIGEST_LENGTH]; rtrn = SHA512_Init(&ctx); if(rtrn < 0) { output->write(ERROR,"Sha init\n"); return (-1); } rtrn = SHA512_Update(&ctx, in, strlen(in)); if(rtrn < 0) { output->write(ERROR,"Can't update input string\n"); return (-1); } rtrn = SHA512_Final(hash, &ctx); if(rtrn < 0) { output->write(ERROR,"Can't do this\n"); return (-1); } (*out) = allocator->alloc((SHA512_DIGEST_LENGTH * 2) + 1); if((*out) == NULL) { output->write(ERROR,"Can't allocate output buf\n"); return (-1); } for(i = 0; i < SHA512_DIGEST_LENGTH; i++) sprintf(*out + (i * 2), "%02x", hash[i]); (*out)[128] = '\0'; return (0); }
void calc_hash(const char *filename) { int n; unsigned char data[BUFFSIZE]; FILE *file = fopen(filename, "rb"); if (file == NULL) { fprintf(stderr, "'%s' ", filename); perror("文件打开失败"); return; } unsigned char md5[MD5_DIGEST_LENGTH]; MD5_CTX md5_c; unsigned char sha1[SHA_DIGEST_LENGTH]; SHA_CTX sha1_c; unsigned char sha512[SHA_DIGEST_LENGTH]; SHA512_CTX sha512_c; MD5_Init(&md5_c); SHA1_Init(&sha1_c); SHA512_Init(&sha512_c); while ((n = fread(data, 1, BUFFSIZE, file)) != 0) { MD5_Update(&md5_c, data, n); SHA1_Update(&sha1_c, data, n); SHA512_Update(&sha512_c, data, n); } MD5_Final(md5, &md5_c); SHA1_Final(sha1, &sha1_c); SHA512_Final(sha512, &sha512_c); int i; printf("%s", filename); printf("\n%8s: ", "MD5"); for (i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", md5[i]); printf("\n%8s: ", "SHA1"); for (i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%02x", sha1[i]); printf("\n%8s: ", "SHA512"); for (i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%02x", sha512[i]); printf("\n"); fclose(file); }
static void generate_ripe(struct ntb_ecc *ecc, struct ntb_key *key) { SHA512_CTX sha_ctx; uint8_t public_key[NTB_ECC_PUBLIC_KEY_SIZE]; uint8_t sha_hash[SHA512_DIGEST_LENGTH]; SHA512_Init(&sha_ctx); ntb_ecc_get_pub_key(ecc, key->signing_key, public_key); SHA512_Update(&sha_ctx, public_key, NTB_ECC_PUBLIC_KEY_SIZE); ntb_ecc_get_pub_key(ecc, key->encryption_key, public_key); SHA512_Update(&sha_ctx, public_key, NTB_ECC_PUBLIC_KEY_SIZE); SHA512_Final(sha_hash, &sha_ctx); RIPEMD160(sha_hash, SHA512_DIGEST_LENGTH, key->address.ripe); }
std::string Digestor::HashPassword(const std::string& plain_pwd) { #if USE_SIMPLE_PWD_HASH return Md5str(plain_pwd); #else uint8_t sha512[64] = {0}; SHA512_CTX sha512_ctx; SHA512_Init(&sha512_ctx); SHA512_Update(&sha512_ctx, plain_pwd.c_str(), plain_pwd.size()); SHA512_Final(sha512, &sha512_ctx); uint8_t md5[16] = {0}; MD5_CTX md5_ctx; MD5_Init(&md5_ctx); MD5_Update(&md5_ctx, sha512, 64); MD5_Final(md5, &md5_ctx); return BinaryHashToHexString(md5, 16); #endif }
char * sha512_hex_hash(const char * passwd) { SHA512_CTX ct; unsigned char hash[SHA512_DIGEST_LENGTH]; static char real_hash[LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1]; // extra char for \0 SHA512_Init(&ct); SHA512_Update(&ct, (const uint8_t*)passwd, strlen(passwd)); SHA512_Final(hash, &ct); /* base64 encode it */ lutil_b64_ntop( hash, SHA512_DIGEST_LENGTH, real_hash, LUTIL_BASE64_ENCODE_LEN(SHA512_DIGEST_LENGTH)+1 ); return real_hash; }
ATF_TC_BODY(t_sha512, tc) { size_t i, j, len; SHA512_CTX ctx; unsigned char buf[512]; unsigned char digest[8 + SHA512_DIGEST_LENGTH]; char output[SHA512_DIGEST_STRING_LENGTH]; for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) { len = strlen(test512[i].vector); for (j = 0; j < 8; ++j) { SHA512_Init(&ctx); memcpy(buf + j, test512[i].vector, len); SHA512_Update(&ctx, buf + j, len); SHA512_Final(digest + j, &ctx); digest2string(digest + j, output, SHA512_DIGEST_LENGTH); ATF_CHECK_STREQ(test512[i].hash, output); } } }
static void _wi_sha2_ctx_final(unsigned char *buffer, _wi_sha2_ctx_t *ctx) { #ifdef WI_SHA2_OPENSSL switch(ctx->bits) { case WI_SHA2_224: SHA224_Final(buffer, &ctx->openssl_256_ctx); break; case WI_SHA2_256: SHA256_Final(buffer, &ctx->openssl_256_ctx); break; case WI_SHA2_384: SHA384_Final(buffer, &ctx->openssl_512_ctx); break; case WI_SHA2_512: SHA512_Final(buffer, &ctx->openssl_512_ctx); break; } #endif #ifdef WI_SHA2_COMMONCRYPTO switch(ctx->bits) { case WI_SHA2_224: CC_SHA224_Final(buffer, &ctx->commondigest_256_ctx); break; case WI_SHA2_256: CC_SHA256_Final(buffer, &ctx->commondigest_256_ctx); break; case WI_SHA2_384: CC_SHA384_Final(buffer, &ctx->commondigest_512_ctx); break; case WI_SHA2_512: CC_SHA512_Final(buffer, &ctx->commondigest_512_ctx); break; } #endif }
static void crypt_all(int count) { int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index++) #endif { SHA512_CTX ctx; SHA512_Init(&ctx); /* First the password */ SHA512_Update(&ctx, saved_key[index], saved_key_length[index]); /* Then the salt, including the $4$ magic */ SHA512_Update(&ctx, cur_salt, salt_len); SHA512_Final((unsigned char*)crypt_out[index], &ctx); } }
static void test_sha512(void) { size_t i; printf("test SHA512\n"); for (i = 0; i < RTEMS_ARRAY_SIZE(test_vectors); ++i) { SHA512_CTX ctx; unsigned char r[64]; const char *s = test_vectors[i]; SHA512_Init(&ctx); SHA512_Update(&ctx, s, strlen(s)); SHA512_Final(r, &ctx); print_result(&r[0], sizeof(r)); rtems_test_assert( memcmp(&r[0], &test_sha512_results[i][0], sizeof(r)) == 0 ); } }
void genkey(const Memblock &string, uint8_t *key, uint32_t length) const { SHA512_CTX ctx; uint32_t numHashes = (length + SHA512_DIGEST_LENGTH - 1) / SHA512_DIGEST_LENGTH; // TODO: This is not very efficient with multiple hashes for (uint32_t i = 0; i < numHashes; i++) { SHA512_Init(&ctx); for (uint32_t j = 0; j < i; j++) { SHA512_Update(&ctx, "\0", 1); } // Find multiplicator int32_t tl = string.length + 8; int32_t mul = 1; while (mul < tl && ((64 * mul) % tl)) { ++mul; } // Try to feed the hash function with 64-byte blocks const int32_t bs = mul * 64; assert(bs <= KEYBUFFER_LENGTH); uint8_t *bptr = m_keybuf + tl; int32_t n = bs / tl; memcpy(m_keybuf + 8, string.data, string.length); while (n-- > 1) { memcpy(bptr, m_keybuf, tl); bptr += tl; } n = m_count / bs; while (n-- > 0) { SHA512_Update(&ctx, m_keybuf, bs); } SHA512_Update(&ctx, m_keybuf, m_count % bs); SHA512_Final(key + (i * SHA512_DIGEST_LENGTH), &ctx); } }
static int __get_patch_file_key(struct itg2_file *file) { unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512_CTX ctx; if (SHA512_Init(&ctx) == 0) return -1; if (SHA512_Update(&ctx, file->header.subkey, file->header.subkey_size) == 0) return -1; if (SHA512_Update(&ctx, ITG2_PATCH_KEY, sizeof(ITG2_PATCH_KEY) - 1) == 0) return -1; if (SHA512_Final(hash, &ctx) == 0) return -1; memcpy(file->aes_key, hash, sizeof(file->aes_key)); return 0; }
int CreateSignTestVector(const char *seed, const char *msg) { unsigned char md[SHA512_DIGEST_LENGTH]; unsigned char Kpub[ed25519_public_key_size]; unsigned char Kprv[ed25519_private_key_size]; unsigned char sig[ed25519_signature_size]; int len = (int)strlen(msg); if (seed) { SHA512_CTX H; SHA512_Init(&H); SHA512_Update(&H, seed, strlen(seed)); SHA512_Final(md, &H); } else { GetRandomBytes(md, 32); } PrintBytes("sk", md, 32); ed25519_CreateKeyPair(Kpub, Kprv, 0, md); PrintBytes("Kpub", Kpub, ed25519_public_key_size); PrintBytes("Kprv", Kprv, ed25519_private_key_size); PrintBytes("m", (const unsigned char*)msg, len); ed25519_SignMessage(sig, Kprv, 0, (const unsigned char*)msg, len); PrintBytes("sig", sig, ed25519_signature_size); if (ed25519_VerifySignature(sig, Kpub, (const unsigned char*)msg, len)) return 0; fprintf(stderr, "Signature verification failed.\n"); return 1; }
/* Generate public and private key pair associated with the secret key */ void ed25519_CreateKeyPair( unsigned char *pubKey, /* OUT: public key */ unsigned char *privKey, /* OUT: private key */ const void *blinding, /* IN: [optional] null or blinding context */ const unsigned char *sk) /* IN: secret key (32 bytes) */ { U8 md[SHA512_DIGEST_LENGTH]; U_WORD t[K_WORDS]; SHA512_CTX H; Affine_POINT Q; /* [a:b] = H(sk) */ SHA512_Init(&H); SHA512_Update(&H, sk, 32); SHA512_Final(md, &H); ecp_TrimSecretKey(md); ecp_BytesToWords(t, md); edp_BasePointMultiply(&Q, t, blinding); ed25519_PackPoint(pubKey, Q.y, Q.x[0]); memcpy(privKey, sk, 32); memcpy(privKey+32, pubKey, 32); }
int MySha::computeSha512(const char * plaintextPath, const char * fileNameHash){ SHA512_CTX sha512; unsigned char hash[SHA512_DIGEST_LENGTH]; int i; FILE *plaintext; FILE *hashFile; char ligne[512]; char pathHash[50]; SHA512_Init(&sha512); if((plaintext = fopen(plaintextPath, "r")) == NULL){ return 1; } else{ while(fgets(ligne, 512, plaintext) != NULL){ SHA512_Update(&sha512, ligne, strlen(ligne)); } SHA512_Final(hash, &sha512); sprintf(pathHash, "../ressources/%s.hash", fileNameHash); // On stocke le hash dans un fichier if((hashFile = fopen(pathHash, "w")) == NULL){ return 1; } else{ for(i=0 ; i<SHA512_DIGEST_LENGTH ; i++){ gmp_fprintf(hashFile, "%02X", hash[i]); } fclose(plaintext); fclose(hashFile); return 0; } } }
static int getentropy_fallback(void *buf, size_t len) { uint8_t results[SHA512_DIGEST_LENGTH]; int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; static int cnt; struct timespec ts; struct timeval tv; struct rusage ru; sigset_t sigset; struct stat st; SHA512_CTX ctx; static pid_t lastpid; pid_t pid; size_t i, ii, m; char *p; struct tcpstat tcpstat; struct udpstat udpstat; struct ipstat ipstat; u_int64_t mach_time; unsigned int idata; void *addr; pid = getpid(); if (lastpid == pid) { faster = 1; repeat = 2; } else { faster = 0; lastpid = pid; repeat = REPEAT; } for (i = 0; i < len; ) { int j; SHA512_Init(&ctx); for (j = 0; j < repeat; j++) { HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } mach_time = mach_absolute_time(); HD(mach_time); ii = sizeof(addr); HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]), &addr, &ii, NULL, 0) == -1, addr); ii = sizeof(idata); HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]), &idata, &ii, NULL, 0) == -1, idata); ii = sizeof(tcpstat); HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]), &tcpstat, &ii, NULL, 0) == -1, tcpstat); ii = sizeof(udpstat); HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]), &udpstat, &ii, NULL, 0) == -1, udpstat); ii = sizeof(ipstat); HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]), &ipstat, &ii, NULL, 0) == -1, ipstat); HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); HX((pid = getppid()) == -1, pid); HX((pid = getpgid(0)) == -1, pid); HX((e = getpriority(0, 0)) == -1, e); if (!faster) { ts.tv_sec = 0; ts.tv_nsec = 1; (void) nanosleep(&ts, NULL); } HX(sigpending(&sigset) == -1, sigset); HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, sigset); HF(getentropy); /* an addr in this library */ HF(printf); /* an addr in libc */ p = (char *)&p; HD(p); /* an addr on stack */ p = (char *)&errno; HD(p); /* the addr of errno */ if (i == 0) { struct sockaddr_storage ss; struct statvfs stvfs; struct termios tios; struct statfs stfs; socklen_t ssl; off_t off; /* * Prime-sized mappings encourage fragmentation; * thus exposing some address entropy. */ struct mm { size_t npg; void *p; } mm[] = { { 17, MAP_FAILED }, { 3, MAP_FAILED }, { 11, MAP_FAILED }, { 2, MAP_FAILED }, { 5, MAP_FAILED }, { 3, MAP_FAILED }, { 7, MAP_FAILED }, { 1, MAP_FAILED }, { 57, MAP_FAILED }, { 3, MAP_FAILED }, { 131, MAP_FAILED }, { 1, MAP_FAILED }, }; for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { HX(mm[m].p = mmap(NULL, mm[m].npg * pgs, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, (off_t)0), mm[m].p); if (mm[m].p != MAP_FAILED) { size_t mo; /* Touch some memory... */ p = mm[m].p; mo = cnt % (mm[m].npg * pgs - 1); p[mo] = 1; cnt += (int)((long)(mm[m].p) / pgs); } /* Check cnts and times... */ mach_time = mach_absolute_time(); HD(mach_time); cnt += (int)mach_time; HX((e = getrusage(RUSAGE_SELF, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { if (mm[m].p != MAP_FAILED) munmap(mm[m].p, mm[m].npg * pgs); mm[m].p = MAP_FAILED; } HX(stat(".", &st) == -1, st); HX(statvfs(".", &stvfs) == -1, stvfs); HX(statfs(".", &stfs) == -1, stfs); HX(stat("/", &st) == -1, st); HX(statvfs("/", &stvfs) == -1, stvfs); HX(statfs("/", &stfs) == -1, stfs); HX((e = fstat(0, &st)) == -1, st); if (e == -1) { if (S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { HX(fstatvfs(0, &stvfs) == -1, stvfs); HX(fstatfs(0, &stfs) == -1, stfs); HX((off = lseek(0, (off_t)0, SEEK_CUR)) < 0, off); } if (S_ISCHR(st.st_mode)) { HX(tcgetattr(0, &tios) == -1, tios); } else if (S_ISSOCK(st.st_mode)) { memset(&ss, 0, sizeof ss); ssl = sizeof(ss); HX(getpeername(0, (void *)&ss, &ssl) == -1, ss); } } HX((e = getrusage(RUSAGE_CHILDREN, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } else { /* Subsequent hashes absorb previous result */ HD(results); } HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } HD(cnt); } SHA512_Final(results, &ctx); memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } explicit_bzero(&ctx, sizeof ctx); explicit_bzero(results, sizeof results); if (gotdata(buf, len) == 0) { errno = save_errno; return (0); /* satisfied */ } errno = EIO; return (-1); }
static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) { /* * The basic DSS signing algorithm is: * * - invent a random k between 1 and q-1 (exclusive). * - Compute r = (g^k mod p) mod q. * - Compute s = k^-1 * (hash + x*r) mod q. * * This has the dangerous properties that: * * - if an attacker in possession of the public key _and_ the * signature (for example, the host you just authenticated * to) can guess your k, he can reverse the computation of s * and work out x = r^-1 * (s*k - hash) mod q. That is, he * can deduce the private half of your key, and masquerade * as you for as long as the key is still valid. * * - since r is a function purely of k and the public key, if * the attacker only has a _range of possibilities_ for k * it's easy for him to work through them all and check each * one against r; he'll never be unsure of whether he's got * the right one. * * - if you ever sign two different hashes with the same k, it * will be immediately obvious because the two signatures * will have the same r, and moreover an attacker in * possession of both signatures (and the public key of * course) can compute k = (hash1-hash2) * (s1-s2)^-1 mod q, * and from there deduce x as before. * * - the Bleichenbacher attack on DSA makes use of methods of * generating k which are significantly non-uniformly * distributed; in particular, generating a 160-bit random * number and reducing it mod q is right out. * * For this reason we must be pretty careful about how we * generate our k. Since this code runs on Windows, with no * particularly good system entropy sources, we can't trust our * RNG itself to produce properly unpredictable data. Hence, we * use a totally different scheme instead. * * What we do is to take a SHA-512 (_big_) hash of the private * key x, and then feed this into another SHA-512 hash that * also includes the message hash being signed. That is: * * proto_k = SHA512 ( SHA512(x) || SHA160(message) ) * * This number is 512 bits long, so reducing it mod q won't be * noticeably non-uniform. So * * k = proto_k mod q * * This has the interesting property that it's _deterministic_: * signing the same hash twice with the same key yields the * same signature. * * Despite this determinism, it's still not predictable to an * attacker, because in order to repeat the SHA-512 * construction that created it, the attacker would have to * know the private key value x - and by assumption he doesn't, * because if he knew that he wouldn't be attacking k! * * (This trick doesn't, _per se_, protect against reuse of k. * Reuse of k is left to chance; all it does is prevent * _excessively high_ chances of reuse of k due to entropy * problems.) * * Thanks to Colin Plumb for the general idea of using x to * ensure k is hard to guess, and to the Cambridge University * Computer Security Group for helping to argue out all the * fine details. */ struct dss_key *dss = (struct dss_key *) key; SHA512_State ss; unsigned char digest[20], digest512[64]; Bignum proto_k, k, gkp, hash, kinv, hxr, r, s; unsigned char *bytes; int nbytes, i; SHA_Simple(data, datalen, digest); /* * Hash some identifying text plus x. */ SHA512_Init(&ss); SHA512_Bytes(&ss, "DSA deterministic k generator", 30); sha512_mpint(&ss, dss->x); SHA512_Final(&ss, digest512); /* * Now hash that digest plus the message hash. */ SHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); SHA512_Bytes(&ss, digest, sizeof(digest)); SHA512_Final(&ss, digest512); memset(&ss, 0, sizeof(ss)); /* * Now convert the result into a bignum, and reduce it mod q. */ proto_k = bignum_from_bytes(digest512, 64); k = bigmod(proto_k, dss->q); freebn(proto_k); memset(digest512, 0, sizeof(digest512)); /* * Now we have k, so just go ahead and compute the signature. */ gkp = modpow(dss->g, k, dss->p); /* g^k mod p */ r = bigmod(gkp, dss->q); /* r = (g^k mod p) mod q */ freebn(gkp); hash = bignum_from_bytes(digest, 20); kinv = modinv(k, dss->q); /* k^-1 mod q */ hxr = bigmuladd(dss->x, r, hash); /* hash + x*r */ s = modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash + x*r) mod q */ freebn(hxr); freebn(kinv); freebn(hash); /* * Signature blob is * * string "ssh-dss" * string two 20-byte numbers r and s, end to end * * i.e. 4+7 + 4+40 bytes. */ nbytes = 4 + 7 + 4 + 40; bytes = snewn(nbytes, unsigned char); PUT_32BIT(bytes, 7); memcpy(bytes + 4, "ssh-dss", 7); PUT_32BIT(bytes + 4 + 7, 40); for (i = 0; i < 20; i++) { bytes[4 + 7 + 4 + i] = bignum_byte(r, 19 - i); bytes[4 + 7 + 4 + 20 + i] = bignum_byte(s, 19 - i); } freebn(r); freebn(s); *siglen = nbytes; return bytes; }
int SHA384_Final(uint8_t *md, SHA512_CTX *sha) { return SHA512_Final(md, sha); }
/* * Create an access check structure, the format depends on the version parameter. * If broken is specified then we create a stucture that isn't conform to the * specification. * * If the structure can't be created then NULL is returned. */ static DATA_BLOB *create_access_check(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *user, bool broken, uint32_t version) { TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB); enum ndr_err_code ndr_err; const struct dom_sid *sid = get_user_sid(tctx, p, tmp_ctx, user); if (sid == NULL) { return NULL; } if (version == 2) { struct bkrp_access_check_v2 access_struct; struct sha sctx; uint8_t nonce[32]; ZERO_STRUCT(access_struct); generate_random_buffer(nonce, sizeof(nonce)); access_struct.nonce_len = sizeof(nonce); access_struct.nonce = nonce; access_struct.sid = *sid; ndr_err = ndr_push_struct_blob(blob, blob, &access_struct, (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } /* * We pushed the whole structure including a null hash * but the hash need to be calculated only up to the hash field * so we reduce the size of what has to be calculated */ SHA1_Init(&sctx); SHA1_Update(&sctx, blob->data, blob->length - sizeof(access_struct.hash)); SHA1_Final(blob->data + blob->length - sizeof(access_struct.hash), &sctx); /* Altering the SHA */ if (broken) { blob->data[blob->length - 1]++; } } if (version == 3) { struct bkrp_access_check_v3 access_struct; struct hc_sha512state sctx; uint8_t nonce[32]; ZERO_STRUCT(access_struct); generate_random_buffer(nonce, sizeof(nonce)); access_struct.nonce_len = sizeof(nonce); access_struct.nonce = nonce; access_struct.sid = *sid; ndr_err = ndr_push_struct_blob(blob, blob, &access_struct, (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } /*We pushed the whole structure including a null hash * but the hash need to be calculated only up to the hash field * so we reduce the size of what has to be calculated */ SHA512_Init(&sctx); SHA512_Update(&sctx, blob->data, blob->length - sizeof(access_struct.hash)); SHA512_Final(blob->data + blob->length - sizeof(access_struct.hash), &sctx); /* Altering the SHA */ if (broken) { blob->data[blob->length -1]++; } } talloc_free(tmp_ctx); return blob; }
int main(void) { SHA512_CTX ctx; uint8_t sum[64]; int result = 0; int i, cnt; for (cnt = 0; cnt < (int)ntests; ++cnt) { SHA512_Init(&ctx); SHA512_Update(&ctx, tests[cnt].input, strlen(tests[cnt].input)); SHA512_Final(sum, &ctx); if (memcmp(tests[cnt].result, sum, 64) != 0) { printf("test %d run %d failed\n", cnt, 1); result = 1; } SHA512_Init(&ctx); for (i = 0; tests[cnt].input[i] != '\0'; ++i) SHA512_Update(&ctx, &tests[cnt].input[i], 1); SHA512_Final(sum, &ctx); if (memcmp(tests[cnt].result, sum, 64) != 0) { printf("test %d run %d failed\n", cnt, 2); result = 1; } } /* Test vector from FIPS 180-2: appendix C.3. */ char buf[1000]; memset(buf, 'a', sizeof(buf)); SHA512_Init(&ctx); for (i = 0; i < 1000; ++i) SHA512_Update(&ctx, buf, sizeof(buf)); SHA512_Final(sum, &ctx); static const char expected[64] = "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b" "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b"; if (memcmp(expected, sum, 64) != 0) { printf("test %d failed\n", cnt); result = 1; } for (cnt = 0; cnt < ntests2; ++cnt) { char *cp = crypt_sha512(tests2[cnt].input, tests2[cnt].salt); if (strcmp(cp, tests2[cnt].expected) != 0) { printf("test %d: expected \"%s\", got \"%s\"\n", cnt, tests2[cnt].expected, cp); result = 1; } } if (result == 0) puts("all tests OK"); return result; }
/* * This function is a wrapper on modpow(). It has the same effect * as modpow(), but employs RSA blinding to protect against timing * attacks. */ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key) { Bignum random, random_encrypted, random_inverse; Bignum input_blinded, ret_blinded; Bignum ret; SHA512_State ss; unsigned char digest512[64]; int digestused = lenof(digest512); int hashseq = 0; /* * Start by inventing a random number chosen uniformly from the * range 2..modulus-1. (We do this by preparing a random number * of the right length and retrying if it's greater than the * modulus, to prevent any potential Bleichenbacher-like * attacks making use of the uneven distribution within the * range that would arise from just reducing our number mod n. * There are timing implications to the potential retries, of * course, but all they tell you is the modulus, which you * already knew.) * * To preserve determinism and avoid Pageant needing to share * the random number pool, we actually generate this `random' * number by hashing stuff with the private key. */ while (1) { int bits, byte, bitsleft, v; random = copybn(key->modulus); /* * Find the topmost set bit. (This function will return its * index plus one.) Then we'll set all bits from that one * downwards randomly. */ bits = bignum_bitcount(random); byte = 0; bitsleft = 0; while (bits--) { if (bitsleft <= 0) { bitsleft = 8; /* * Conceptually the following few lines are equivalent to * byte = random_byte(); */ if (digestused >= lenof(digest512)) { unsigned char seqbuf[4]; PUT_32BIT(seqbuf, hashseq); SHA512_Init(&ss); SHA512_Bytes(&ss, "RSA deterministic blinding", 26); SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf)); sha512_mpint(&ss, key->private_exponent); SHA512_Final(&ss, digest512); hashseq++; /* * Now hash that digest plus the signature * input. */ SHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); sha512_mpint(&ss, input); SHA512_Final(&ss, digest512); digestused = 0; } byte = digest512[digestused++]; } v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(random, bits, v); } /* * Now check that this number is strictly greater than * zero, and strictly less than modulus. */ if (bignum_cmp(random, Zero) <= 0 || bignum_cmp(random, key->modulus) >= 0) { freebn(random); continue; } else { break; } } /* * RSA blinding relies on the fact that (xy)^d mod n is equal * to (x^d mod n) * (y^d mod n) mod n. We invent a random pair * y and y^d; then we multiply x by y, raise to the power d mod * n as usual, and divide by y^d to recover x^d. Thus an * attacker can't correlate the timing of the modpow with the * input, because they don't know anything about the number * that was input to the actual modpow. * * The clever bit is that we don't have to do a huge modpow to * get y and y^d; we will use the number we just invented as * _y^d_, and use the _public_ exponent to compute (y^d)^e = y * from it, which is much faster to do. */ random_encrypted = modpow(random, key->exponent, key->modulus); random_inverse = modinv(random, key->modulus); input_blinded = modmul(input, random_encrypted, key->modulus); ret_blinded = modpow(input_blinded, key->private_exponent, key->modulus); ret = modmul(ret_blinded, random_inverse, key->modulus); freebn(ret_blinded); freebn(input_blinded); freebn(random_inverse); freebn(random_encrypted); freebn(random); return ret; }
void ALSZOTExtRec::ComputeOWF(std::queue<alsz_rcv_check_t>* check_buf_q, channel* check_chan) {//linking_t* permbits, int nchecks, int otid, int processedOTs, BYTE* outhashes) { //Obtain T0 and T1 from the SeedPointers uint32_t receiver_hashes = 4; uint64_t tmpid, tmpnblocks; linking_t* perm; uint8_t* rcv_buf = check_chan->blocking_receive_id_len((uint8_t**) &perm, &tmpid, &tmpnblocks); alsz_rcv_check_t check_buf = check_buf_q->front(); check_buf_q->pop(); assert(tmpid == check_buf.otid); assert(tmpnblocks == check_buf.numblocks); //the bufsize has to be padded to a multiple of the PRF-size since we will omit boundary checks there uint32_t i, k; uint64_t bufrowbytelen = m_nBlockSizeBytes * check_buf.numblocks;//seedptr->expstrbitlen>>3;//(CEIL_DIVIDE(processedOTs, wd_size_bits) * wd_size_bits) >>3; //contains the T-matrix uint8_t* T0 = check_buf.T0; //contains the T-matrix XOR the receive bits uint8_t* T1 = check_buf.T1; uint32_t outhashbytelen = m_nChecks * OWF_BYTES * receiver_hashes; uint8_t* outhashes = (uint8_t*) malloc(outhashbytelen); #ifdef OTTiming_PRECISE timespec tstart, tend; double total_xortime = 0, total_hashtime = 0; #endif #ifdef AES_OWF AES_KEY_CTX aesowfkey; MPC_AES_KEY_INIT(&aesowfkey); #else uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); #endif //uint8_t* tmpbuf = (uint8_t**) malloc(bufrowbytelen); uint8_t** tmpbuf = (uint8_t**) malloc(receiver_hashes * sizeof(uint8_t*)); for(i = 0; i < receiver_hashes; i++) { tmpbuf[i] = (uint8_t*) malloc(bufrowbytelen); } uint8_t **ka = (uint8_t**) malloc(2 * sizeof(uint8_t*)); uint8_t **kb = (uint8_t**) malloc(2 * sizeof(uint8_t*)); // uint8_t *kaptr, *kbptr; uint8_t* outptr = outhashes; uint32_t iters = bufrowbytelen / sizeof(uint64_t); SHA512_CTX sha, shatmp; SHA512_Init(&sha); SHA512_Init(&shatmp); //Compute all hashes for the permutations given Ta and Tb for(i = 0; i < m_nChecks; i++) { ka[0] = T0 + perm[i].ida * bufrowbytelen; ka[1] = T1 + perm[i].ida * bufrowbytelen; kb[0] = T0 + perm[i].idb * bufrowbytelen; kb[1] = T1 + perm[i].idb * bufrowbytelen; //std::cout << "ida = " << perm[i].ida <<", idb= " << perm[i].idb << std::endl; //XOR all four possibilities #ifdef DEBUG_ALSZ_CHECKS std::cout << i << "-th check: between " << perm[i].ida << ", and " << perm[i].idb << ": " << std::endl; #endif for(k = 0; k < iters; k++) { ((uint64_t*) tmpbuf[0])[k] = ((uint64_t*) ka[0])[k] ^ ((uint64_t*) kb[0])[k]; ((uint64_t*) tmpbuf[1])[k] = ((uint64_t*) ka[0])[k] ^ ((uint64_t*) kb[1])[k]; ((uint64_t*) tmpbuf[2])[k] = ((uint64_t*) ka[1])[k] ^ ((uint64_t*) kb[0])[k]; ((uint64_t*) tmpbuf[3])[k] = ((uint64_t*) ka[1])[k] ^ ((uint64_t*) kb[1])[k]; } sha = shatmp; //sha512_hash(outptr, OWF_BYTES, tmpbuf[0], bufrowbytelen, hash_buf); SHA512_Update(&sha, tmpbuf[0], bufrowbytelen); SHA512_Final(hash_buf, &sha); memcpy(outptr, hash_buf, OWF_BYTES); outptr+=OWF_BYTES; //sha512_hash(outptr, OWF_BYTES, tmpbuf[1], bufrowbytelen, hash_buf); sha = shatmp; SHA512_Update(&sha, tmpbuf[1], bufrowbytelen); SHA512_Final(hash_buf, &sha); memcpy(outptr, hash_buf, OWF_BYTES); outptr+=OWF_BYTES; //sha512_hash(outptr, OWF_BYTES, tmpbuf[2], bufrowbytelen, hash_buf); sha = shatmp; SHA512_Update(&sha, tmpbuf[2], bufrowbytelen); SHA512_Final(hash_buf, &sha); memcpy(outptr, hash_buf, OWF_BYTES); outptr+=OWF_BYTES; //sha512_hash(outptr, OWF_BYTES, tmpbuf[3], bufrowbytelen, hash_buf); sha = shatmp; SHA512_Update(&sha, tmpbuf[3], bufrowbytelen); SHA512_Final(hash_buf, &sha); memcpy(outptr, hash_buf, OWF_BYTES); outptr+=OWF_BYTES; /* for(j = 0; j < receiver_hashes; j++, outptr+=OWF_BYTES) { #ifdef OTTiming_PRECISE clock_gettime(CLOCK_MONOTONIC, &tstart); #endif kaptr = ka[j>>1]; kbptr = kb[j&0x01]; for(k = 0; k < iters; k++) { ((uint64_t*) tmpbuf)[k] = ((uint64_t*) kaptr)[k] ^ ((uint64_t*) kbptr)[k]; } #ifdef DEBUG_ALSZ_CHECKS_INPUT std::cout << (std::hex) << "\t"; for(uint32_t t = 0; t < bufrowbytelen; t++) { std::cout << std::setw(2) << std::setfill('0') << (uint32_t) tmpbuf[t]; } std::cout << (std::dec) << std::endl; #endif #ifdef AES_OWF owf(&aesowfkey, rowbytelen, tmpbuf, outptr); #else #ifdef OTTiming_PRECISE clock_gettime(CLOCK_MONOTONIC, &tend); total_xortime += getMillies(tstart, tend); clock_gettime(CLOCK_MONOTONIC, &tstart); #endif sha512_hash(outptr, OWF_BYTES, tmpbuf, bufrowbytelen, hash_buf); //m_cCrypt->hash_buf(outptr, OWF_BYTES, tmpbuf, bufrowbytelen, hash_buf); #ifdef OTTiming_PRECISE clock_gettime(CLOCK_MONOTONIC, &tend); total_hashtime += getMillies(tstart, tend); #endif #endif #ifdef DEBUG_ALSZ_CHECKS_OUTPUT std::cout << (std::hex) << "\t"; for(uint32_t t = 0; t < OWF_BYTES; t++) { std::cout << (uint32_t) outptr[t]; } std::cout << (std::dec) << std::endl; #endif }*/ } check_chan->send_id_len(outhashes, outhashbytelen, check_buf.otid, check_buf.numblocks); #ifdef OTTiming_PRECISE std::cout << "Total XOR Time:\t" << total_xortime << " ms"<< std::endl; std::cout << "Total Hash Time:\t" << total_hashtime << " ms"<< std::endl; #endif free(rcv_buf); for (uint32_t i = 0; i < receiver_hashes; i++) { free(tmpbuf[i]); } free(tmpbuf); free(ka); free(kb); free(check_buf.T0); free(check_buf.T1); free(outhashes); #ifndef AES_OWF free(hash_buf); #endif }
/* * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike * BN_rand_range, it also includes the contents of |priv| and |message| in * the generation so that an RNG failure isn't fatal as long as |priv| * remains secret. This is intended for use in DSA and ECDSA where an RNG * weakness leads directly to private key exposure unless this function is * used. */ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv, const unsigned char *message, size_t message_len, BN_CTX *ctx) { SHA512_CTX sha; /* * We use 512 bits of random data per iteration to ensure that we have at * least |range| bits of randomness. */ unsigned char random_bytes[64]; unsigned char digest[SHA512_DIGEST_LENGTH]; unsigned done, todo; /* We generate |range|+8 bytes of random output. */ const unsigned num_k_bytes = BN_num_bytes(range) + 8; unsigned char private_bytes[96]; unsigned char *k_bytes; int ret = 0; k_bytes = OPENSSL_malloc(num_k_bytes); if (!k_bytes) goto err; /* We copy |priv| into a local buffer to avoid exposing its length. */ todo = sizeof(priv->d[0]) * priv->top; if (todo > sizeof(private_bytes)) { /* * No reasonable DSA or ECDSA key should have a private key this * large and we don't handle this case in order to avoid leaking the * length of the private key. */ BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE); goto err; } memcpy(private_bytes, priv->d, todo); memset(private_bytes + todo, 0, sizeof(private_bytes) - todo); for (done = 0; done < num_k_bytes;) { if (RAND_bytes(random_bytes, sizeof(random_bytes)) != 1) goto err; SHA512_Init(&sha); SHA512_Update(&sha, &done, sizeof(done)); SHA512_Update(&sha, private_bytes, sizeof(private_bytes)); SHA512_Update(&sha, message, message_len); SHA512_Update(&sha, random_bytes, sizeof(random_bytes)); SHA512_Final(digest, &sha); todo = num_k_bytes - done; if (todo > SHA512_DIGEST_LENGTH) todo = SHA512_DIGEST_LENGTH; memcpy(k_bytes + done, digest, todo); done += todo; } if (!BN_bin2bn(k_bytes, num_k_bytes, out)) goto err; if (BN_mod(out, out, range, ctx) != 1) goto err; ret = 1; err: OPENSSL_free(k_bytes); return ret; }
static int getentropy_fallback(void *buf, size_t len) { uint8_t results[SHA512_DIGEST_LENGTH]; int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat; static int cnt; struct timespec ts; struct timeval tv; perfstat_cpu_total_t cpustats; #ifdef _AIX61 perfstat_cpu_total_wpar_t cpustats_wpar; #endif perfstat_partition_total_t lparstats; perfstat_disk_total_t diskinfo; perfstat_netinterface_total_t netinfo; struct rusage ru; sigset_t sigset; struct stat st; SHA512_CTX ctx; static pid_t lastpid; pid_t pid; size_t i, ii, m; char *p; pid = getpid(); if (lastpid == pid) { faster = 1; repeat = 2; } else { faster = 0; lastpid = pid; repeat = REPEAT; } for (i = 0; i < len; ) { int j; SHA512_Init(&ctx); for (j = 0; j < repeat; j++) { HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } HX(perfstat_cpu_total(NULL, &cpustats, sizeof(cpustats), 1) == -1, cpustats); #ifdef _AIX61 HX(perfstat_cpu_total_wpar(NULL, &cpustats_wpar, sizeof(cpustats_wpar), 1) == -1, cpustats_wpar); #endif HX(perfstat_partition_total(NULL, &lparstats, sizeof(lparstats), 1) == -1, lparstats); HX(perfstat_disk_total(NULL, &diskinfo, sizeof(diskinfo), 1) == -1, diskinfo); HX(perfstat_netinterface_total(NULL, &netinfo, sizeof(netinfo), 1) == -1, netinfo); for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) HX(clock_gettime(cl[ii], &ts) == -1, ts); HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); HX((pid = getppid()) == -1, pid); HX((pid = getpgid(0)) == -1, pid); HX((e = getpriority(0, 0)) == -1, e); if (!faster) { ts.tv_sec = 0; ts.tv_nsec = 1; (void) nanosleep(&ts, NULL); } HX(sigpending(&sigset) == -1, sigset); HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, sigset); HF(getentropy); /* an addr in this library */ HF(printf); /* an addr in libc */ p = (char *)&p; HD(p); /* an addr on stack */ p = (char *)&errno; HD(p); /* the addr of errno */ if (i == 0) { struct sockaddr_storage ss; struct statvfs stvfs; struct termios tios; socklen_t ssl; off_t off; /* * Prime-sized mappings encourage fragmentation; * thus exposing some address entropy. */ struct mm { size_t npg; void *p; } mm[] = { { 17, MAP_FAILED }, { 3, MAP_FAILED }, { 11, MAP_FAILED }, { 2, MAP_FAILED }, { 5, MAP_FAILED }, { 3, MAP_FAILED }, { 7, MAP_FAILED }, { 1, MAP_FAILED }, { 57, MAP_FAILED }, { 3, MAP_FAILED }, { 131, MAP_FAILED }, { 1, MAP_FAILED }, }; for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { HX(mm[m].p = mmap(NULL, mm[m].npg * pgs, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, (off_t)0), mm[m].p); if (mm[m].p != MAP_FAILED) { size_t mo; /* Touch some memory... */ p = mm[m].p; mo = cnt % (mm[m].npg * pgs - 1); p[mo] = 1; cnt += (int)((long)(mm[m].p) / pgs); } /* Check cnts and times... */ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) { HX((e = clock_gettime(cl[ii], &ts)) == -1, ts); if (e != -1) cnt += (int)ts.tv_nsec; } HX((e = getrusage(RUSAGE_SELF, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { if (mm[m].p != MAP_FAILED) munmap(mm[m].p, mm[m].npg * pgs); mm[m].p = MAP_FAILED; } HX(stat(".", &st) == -1, st); HX(statvfs(".", &stvfs) == -1, stvfs); HX(stat("/", &st) == -1, st); HX(statvfs("/", &stvfs) == -1, stvfs); HX((e = fstat(0, &st)) == -1, st); if (e == -1) { if (S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { HX(fstatvfs(0, &stvfs) == -1, stvfs); HX((off = lseek(0, (off_t)0, SEEK_CUR)) < 0, off); } if (S_ISCHR(st.st_mode)) { HX(tcgetattr(0, &tios) == -1, tios); } else if (S_ISSOCK(st.st_mode)) { memset(&ss, 0, sizeof ss); ssl = sizeof(ss); HX(getpeername(0, (void *)&ss, &ssl) == -1, ss); } } HX((e = getrusage(RUSAGE_CHILDREN, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } else { /* Subsequent hashes absorb previous result */ HD(results); } HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } HD(cnt); } SHA512_Final(results, &ctx); memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } explicit_bzero(&ctx, sizeof ctx); explicit_bzero(results, sizeof results); if (gotdata(buf, len) == 0) { errno = save_errno; return 0; /* satisfied */ } errno = EIO; return -1; }
bool Digestor::HashFile(const std::string &path, int required, ByteArray &res) { const int kBufferSize = 1024 * 16; //FileInfo::FileStatus st_before = FileInfo::StatFile(path); unsigned char md5hash[16] = {0}; unsigned char sha1hash[20] = {0}; unsigned char sha512hash[64] = {0}; MD5_CTX md5ctx; SHA_CTX sha1ctx; SHA512_CTX sha512ctx; MD5_Init(&md5ctx); SHA1_Init(&sha1ctx); SHA512_Init(&sha512ctx); File inf; char buffer[kBufferSize]; if (!inf.OpenForRead(path)) { return false; } unsigned long read_bytes; while (1) { if (!inf.Read(buffer, kBufferSize, &read_bytes)) { inf.Close(); return false; } if (read_bytes == 0) break; if (required & HASH_MD5) MD5_Update(&md5ctx, buffer, read_bytes); if (required & HASH_SHA1) SHA1_Update(&sha1ctx, buffer, read_bytes); if (required & HASH_SHA512) SHA512_Update(&sha512ctx, buffer, read_bytes); } inf.Close(); if (required & HASH_MD5) { MD5_Final(md5hash, &md5ctx); res.insert(res.end(), md5hash, md5hash + 16); } if (required & HASH_SHA1) { SHA1_Final(sha1hash, &sha1ctx); res.insert(res.end(), sha1hash, sha1hash + 20); } if (required & HASH_SHA512) { SHA512_Final(sha512hash, &sha512ctx); res.insert(res.end(), sha512hash, sha512hash + 64); } // FileInfo::FileStatus st_after = FileInfo::StatFile(path); // if (st_before.size != st_after.size || st_before.modifytime != st_after.modifytime) { // res.clear(); // return false; // } return true; }
static char * crypt_sha512_r(const char *key, const char *salt, char *buffer, int buflen) { u_long srounds; int n; uint8_t alt_result[64], temp_result[64]; SHA512_CTX ctx, alt_ctx; size_t salt_len, key_len, cnt, rounds; char *cp, *copied_key, *copied_salt, *p_bytes, *s_bytes, *endp; const char *num; bool rounds_custom; copied_key = NULL; copied_salt = NULL; /* Default number of rounds. */ rounds = ROUNDS_DEFAULT; rounds_custom = false; /* Find beginning of salt string. The prefix should normally always * be present. Just in case it is not. */ if (strncmp(sha512_salt_prefix, salt, sizeof(sha512_salt_prefix) - 1) == 0) /* Skip salt prefix. */ salt += sizeof(sha512_salt_prefix) - 1; if (strncmp(salt, sha512_rounds_prefix, sizeof(sha512_rounds_prefix) - 1) == 0) { num = salt + sizeof(sha512_rounds_prefix) - 1; srounds = strtoul(num, &endp, 10); if (*endp == '$') { salt = endp + 1; rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX)); rounds_custom = true; } } salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX); key_len = strlen(key); /* Prepare for the real work. */ SHA512_Init(&ctx); /* Add the key string. */ SHA512_Update(&ctx, key, key_len); /* The last part is the salt string. This must be at most 8 * characters and it ends at the first `$' character (for * compatibility with existing implementations). */ SHA512_Update(&ctx, salt, salt_len); /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The * final result will be added to the first context. */ SHA512_Init(&alt_ctx); /* Add key. */ SHA512_Update(&alt_ctx, key, key_len); /* Add salt. */ SHA512_Update(&alt_ctx, salt, salt_len); /* Add key again. */ SHA512_Update(&alt_ctx, key, key_len); /* Now get result of this (64 bytes) and add it to the other context. */ SHA512_Final(alt_result, &alt_ctx); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 64; cnt -= 64) SHA512_Update(&ctx, alt_result, 64); SHA512_Update(&ctx, alt_result, cnt); /* Take the binary representation of the length of the key and for * every 1 add the alternate sum, for every 0 the key. */ for (cnt = key_len; cnt > 0; cnt >>= 1) if ((cnt & 1) != 0) SHA512_Update(&ctx, alt_result, 64); else SHA512_Update(&ctx, key, key_len); /* Create intermediate result. */ SHA512_Final(alt_result, &ctx); /* Start computation of P byte sequence. */ SHA512_Init(&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < key_len; ++cnt) SHA512_Update(&alt_ctx, key, key_len); /* Finish the digest. */ SHA512_Final(temp_result, &alt_ctx); /* Create byte sequence P. */ cp = p_bytes = alloca(key_len); for (cnt = key_len; cnt >= 64; cnt -= 64) { memcpy(cp, temp_result, 64); cp += 64; } memcpy(cp, temp_result, cnt); /* Start computation of S byte sequence. */ SHA512_Init(&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) SHA512_Update(&alt_ctx, salt, salt_len); /* Finish the digest. */ SHA512_Final(temp_result, &alt_ctx); /* Create byte sequence S. */ cp = s_bytes = alloca(salt_len); for (cnt = salt_len; cnt >= 64; cnt -= 64) { memcpy(cp, temp_result, 64); cp += 64; } memcpy(cp, temp_result, cnt); /* Repeatedly run the collected hash value through SHA512 to burn CPU * cycles. */ for (cnt = 0; cnt < rounds; ++cnt) { /* New context. */ SHA512_Init(&ctx); /* Add key or last result. */ if ((cnt & 1) != 0) SHA512_Update(&ctx, p_bytes, key_len); else SHA512_Update(&ctx, alt_result, 64); /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) SHA512_Update(&ctx, s_bytes, salt_len); /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) SHA512_Update(&ctx, p_bytes, key_len); /* Add key or last result. */ if ((cnt & 1) != 0) SHA512_Update(&ctx, alt_result, 64); else SHA512_Update(&ctx, p_bytes, key_len); /* Create intermediate result. */ SHA512_Final(alt_result, &ctx); } /* Now we can construct the result string. It consists of three * parts. */ cp = stpncpy(buffer, sha512_salt_prefix, MAX(0, buflen)); buflen -= sizeof(sha512_salt_prefix) - 1; if (rounds_custom) { n = snprintf(cp, MAX(0, buflen), "%s%zu$", sha512_rounds_prefix, rounds); cp += n; buflen -= n; } cp = stpncpy(cp, salt, MIN((size_t)MAX(0, buflen), salt_len)); buflen -= MIN((size_t)MAX(0, buflen), salt_len); if (buflen > 0) { *cp++ = '$'; --buflen; } b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4, &buflen, &cp); b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4, &buflen, &cp); b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4, &buflen, &cp); b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4, &buflen, &cp); b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4, &buflen, &cp); b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4, &buflen, &cp); b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4, &buflen, &cp); b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4, &buflen, &cp); b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4, &buflen, &cp); b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4, &buflen, &cp); b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4, &buflen, &cp); b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4, &buflen, &cp); b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4, &buflen, &cp); b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4, &buflen, &cp); b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4, &buflen, &cp); b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4, &buflen, &cp); b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4, &buflen, &cp); b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4, &buflen, &cp); b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4, &buflen, &cp); b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4, &buflen, &cp); b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4, &buflen, &cp); b64_from_24bit(0, 0, alt_result[63], 2, &buflen, &cp); if (buflen <= 0) { errno = ERANGE; buffer = NULL; } else *cp = '\0'; /* Terminate the string. */ /* Clear the buffer for the intermediate result so that people * attaching to processes or reading core dumps cannot get any * information. We do it in this way to clear correct_words[] inside * the SHA512 implementation as well. */ SHA512_Init(&ctx); SHA512_Final(alt_result, &ctx); memset(temp_result, '\0', sizeof(temp_result)); memset(p_bytes, '\0', key_len); memset(s_bytes, '\0', salt_len); memset(&ctx, '\0', sizeof(ctx)); memset(&alt_ctx, '\0', sizeof(alt_ctx)); if (copied_key != NULL) memset(copied_key, '\0', key_len); if (copied_salt != NULL) memset(copied_salt, '\0', salt_len); return buffer; }