int secalgo_ds_digest(int algo, unsigned char* buf, size_t len, unsigned char* res) { /* uses libNSS */ switch(algo) { #ifdef USE_SHA1 case LDNS_SHA1: return HASH_HashBuf(HASH_AlgSHA1, res, buf, len) == SECSuccess; #endif #if defined(USE_SHA2) case LDNS_SHA256: return HASH_HashBuf(HASH_AlgSHA256, res, buf, len) == SECSuccess; #endif #ifdef USE_ECDSA case LDNS_SHA384: return HASH_HashBuf(HASH_AlgSHA384, res, buf, len) == SECSuccess; #endif case LDNS_HASH_GOST: default: verbose(VERB_QUERY, "unknown DS digest algorithm %d", algo); break; } return 0; }
size_t nsec3_get_hashed(ldns_buffer* buf, uint8_t* nm, size_t nmlen, int algo, size_t iter, uint8_t* salt, size_t saltlen, uint8_t* res, size_t max) { size_t i, hash_len; /* prepare buffer for first iteration */ ldns_buffer_clear(buf); ldns_buffer_write(buf, nm, nmlen); query_dname_tolower(ldns_buffer_begin(buf)); ldns_buffer_write(buf, salt, saltlen); ldns_buffer_flip(buf); switch(algo) { #if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS) case NSEC3_HASH_SHA1: #ifdef HAVE_SSL hash_len = SHA_DIGEST_LENGTH; #else hash_len = SHA1_LENGTH; #endif if(hash_len > max) return 0; # ifdef HAVE_SSL (void)SHA1((unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf), (unsigned char*)res); # else (void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)res, (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf)); # endif for(i=0; i<iter; i++) { ldns_buffer_clear(buf); ldns_buffer_write(buf, res, hash_len); ldns_buffer_write(buf, salt, saltlen); ldns_buffer_flip(buf); # ifdef HAVE_SSL (void)SHA1( (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf), (unsigned char*)res); # else (void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)res, (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf)); # endif } break; #endif /* HAVE_EVP_SHA1 or NSS */ default: log_err("nsec3 hash of unknown algo %d", algo); return 0; } return hash_len; }
TACK_RETVAL tackNssHashFunc(uint8_t* input, uint32_t inputLen, uint8_t output[TACK_HASH_LENGTH]) { SECStatus rv = HASH_HashBuf(HASH_AlgSHA256, output, input, inputLen); if (rv == SECSuccess) return TACK_OK; else return TACK_ERR_CRYPTO_FUNC; }
/* perform nsec3 hash. return false on failure */ int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { case NSEC3_HASH_SHA1: (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len); return 1; default: return 0; } }
static SECStatus DigestContent (SECItem * digest, SECItem * content, HASH_HashType hashType) { unsigned int maxLen = digest->len; unsigned int len = HASH_ResultLen(hashType); SECStatus rv; if (len > maxLen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } rv = HASH_HashBuf(hashType, digest->data, content->data, content->len); if (rv == SECSuccess) digest->len = len; return rv; }
nsresult DtlsIdentity::ComputeFingerprint(const UniqueCERTCertificate& cert, const std::string algorithm, uint8_t *digest, size_t size, size_t *digest_length) { MOZ_ASSERT(cert); HASH_HashType ht; if (algorithm == "sha-1") { ht = HASH_AlgSHA1; } else if (algorithm == "sha-224") { ht = HASH_AlgSHA224; } else if (algorithm == "sha-256") { ht = HASH_AlgSHA256; } else if (algorithm == "sha-384") { ht = HASH_AlgSHA384; } else if (algorithm == "sha-512") { ht = HASH_AlgSHA512; } else { return NS_ERROR_INVALID_ARG; } const SECHashObject *ho = HASH_GetHashObject(ht); MOZ_ASSERT(ho); if (!ho) { return NS_ERROR_INVALID_ARG; } MOZ_ASSERT(ho->length >= 20); // Double check if (size < ho->length) { return NS_ERROR_INVALID_ARG; } SECStatus rv = HASH_HashBuf(ho->type, digest, cert->derCert.data, cert->derCert.len); if (rv != SECSuccess) { return NS_ERROR_FAILURE; } *digest_length = ho->length; return NS_OK; }
static int nr_crypto_nss_md5(UCHAR *buf, int bufl, UCHAR *result) { int err = R_INTERNAL; SECStatus rv; const SECHashObject *ho = HASH_GetHashObject(HASH_AlgMD5); MOZ_ASSERT(ho); if (!ho) goto abort; MOZ_ASSERT(ho->length == 16); rv = HASH_HashBuf(ho->type, result, buf, bufl); if (rv != SECSuccess) goto abort; err = 0; abort: return err; }
void secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) { (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); }
/** * Check a canonical sig+rrset and signature against a dnskey * @param buf: buffer with data to verify, the first rrsig part and the * canonicalized rrset. * @param algo: DNSKEY algorithm. * @param sigblock: signature rdata field from RRSIG * @param sigblock_len: length of sigblock data. * @param key: public key data from DNSKEY RR. * @param keylen: length of keydata. * @param reason: bogus reason in more detail. * @return secure if verification succeeded, bogus on crypto failure, * unchecked on format errors and alloc failures. */ enum sec_status verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen, char** reason) { /* uses libNSS */ /* large enough for the different hashes */ unsigned char hash[HASH_LENGTH_MAX]; unsigned char hash2[HASH_LENGTH_MAX*2]; HASH_HashType htype = 0; SECKEYPublicKey* pubkey = NULL; SECItem secsig = {siBuffer, sigblock, sigblock_len}; SECItem sechash = {siBuffer, hash, 0}; SECStatus res; unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */ size_t prefixlen = 0; int err; if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen, &prefix, &prefixlen)) { verbose(VERB_QUERY, "verify: failed to setup key"); *reason = "use of key for crypto failed"; SECKEY_DestroyPublicKey(pubkey); return sec_status_bogus; } #if defined(USE_DSA) && defined(USE_SHA1) /* need to convert DSA, ECDSA signatures? */ if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) { if(sigblock_len == 1+2*SHA1_LENGTH) { secsig.data ++; secsig.len --; } else { SECItem* p = DSAU_DecodeDerSig(&secsig); if(!p) { verbose(VERB_QUERY, "verify: failed DER decode"); *reason = "signature DER decode failed"; SECKEY_DestroyPublicKey(pubkey); return sec_status_bogus; } if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) { log_err("alloc failure in DER decode"); SECKEY_DestroyPublicKey(pubkey); SECITEM_FreeItem(p, PR_TRUE); return sec_status_unchecked; } SECITEM_FreeItem(p, PR_TRUE); } } #endif /* USE_DSA */ /* do the signature cryptography work */ /* hash the data */ sechash.len = HASH_ResultLen(htype); if(sechash.len > sizeof(hash)) { verbose(VERB_QUERY, "verify: hash too large for buffer"); SECKEY_DestroyPublicKey(pubkey); return sec_status_unchecked; } if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf)) != SECSuccess) { verbose(VERB_QUERY, "verify: HASH_HashBuf failed"); SECKEY_DestroyPublicKey(pubkey); return sec_status_unchecked; } if(prefix) { int hashlen = sechash.len; if(prefixlen+hashlen > sizeof(hash2)) { verbose(VERB_QUERY, "verify: hashprefix too large"); SECKEY_DestroyPublicKey(pubkey); return sec_status_unchecked; } sechash.data = hash2; sechash.len = prefixlen+hashlen; memcpy(sechash.data, prefix, prefixlen); memmove(sechash.data+prefixlen, hash, hashlen); } /* verify the signature */ res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/); SECKEY_DestroyPublicKey(pubkey); if(res == SECSuccess) { return sec_status_secure; } err = PORT_GetError(); if(err != SEC_ERROR_BAD_SIGNATURE) { /* failed to verify */ verbose(VERB_QUERY, "verify: PK11_Verify failed: %s", PORT_ErrorToString(err)); /* if it is not supported, like ECC is removed, we get, * SEC_ERROR_NO_MODULE */ if(err == SEC_ERROR_NO_MODULE) return sec_status_unchecked; /* but other errors are commonly returned * for a bad signature from NSS. Thus we return bogus, * not unchecked */ *reason = "signature crypto failed"; return sec_status_bogus; } verbose(VERB_QUERY, "verify: signature mismatch: %s", PORT_ErrorToString(err)); *reason = "signature crypto failed"; return sec_status_bogus; }
/** perform hash of name */ static int nsec3_calc_hash(struct regional* region, ldns_buffer* buf, struct nsec3_cached_hash* c) { int algo = nsec3_get_algo(c->nsec3, c->rr); size_t iter = nsec3_get_iter(c->nsec3, c->rr); uint8_t* salt; size_t saltlen, i; if(!nsec3_get_salt(c->nsec3, c->rr, &salt, &saltlen)) return -1; /* prepare buffer for first iteration */ ldns_buffer_clear(buf); ldns_buffer_write(buf, c->dname, c->dname_len); query_dname_tolower(ldns_buffer_begin(buf)); ldns_buffer_write(buf, salt, saltlen); ldns_buffer_flip(buf); switch(algo) { #if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS) case NSEC3_HASH_SHA1: #ifdef HAVE_SSL c->hash_len = SHA_DIGEST_LENGTH; #else c->hash_len = SHA1_LENGTH; #endif c->hash = (uint8_t*)regional_alloc(region, c->hash_len); if(!c->hash) return 0; # ifdef HAVE_SSL (void)SHA1((unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf), (unsigned char*)c->hash); # else (void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)c->hash, (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf)); # endif for(i=0; i<iter; i++) { ldns_buffer_clear(buf); ldns_buffer_write(buf, c->hash, c->hash_len); ldns_buffer_write(buf, salt, saltlen); ldns_buffer_flip(buf); # ifdef HAVE_SSL (void)SHA1( (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf), (unsigned char*)c->hash); # else (void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)c->hash, (unsigned char*)ldns_buffer_begin(buf), (unsigned long)ldns_buffer_limit(buf)); # endif } break; #endif /* HAVE_EVP_SHA1 or NSS */ default: log_err("nsec3 hash of unknown algo %d", algo); return -1; } return 1; }