DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs ¶meters) const { bool invalid = false; #if defined(CRYPTOPP_CXX11) std::unique_ptr<HashTransformation> pHash(NewHash()); #else std::auto_ptr<HashTransformation> pHash(NewHash()); #endif // convert from bit length to byte length if (oaepBlockLen % 8 != 0) { invalid = (oaepBlock[0] != 0) || invalid; oaepBlock++; } oaepBlockLen /= 8; const size_t hLen = pHash->DigestSize(); const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; invalid = (oaepBlockLen < 2*hLen+1) || invalid; SecByteBlock t(oaepBlock, oaepBlockLen); byte *const maskedSeed = t; byte *const maskedDB = t+seedLen; #if defined(CRYPTOPP_CXX11) std::unique_ptr<MaskGeneratingFunction> pMGF(NewMGF()); #else std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF()); #endif pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); ConstByteArrayParameter encodingParameters; parameters.GetValue(Name::EncodingParameters(), encodingParameters); // DB = pHash' || 00 ... || 01 || M byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); invalid = (M == maskedDB+dbLen) || invalid; invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to<byte>(), byte(0))) != M) || invalid; invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid; if (invalid) return DecodingResult(); M++; memcpy(output, M, maskedDB+dbLen-M); return DecodingResult(maskedDB+dbLen-M); }
int DFlushEntry(afs_int32 *fid) { /* Flush pages modified by one entry. */ struct buffer *tb; int code; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(fid)]; tb; tb = tb->hashNext) if (FidEq(tb->fid, fid) && tb->dirty) { ObtainWriteLock(&tb->lock); if (tb->dirty) { code = ReallyWrite(tb->fid, tb->page, tb->data); if (code) { ReleaseWriteLock(&tb->lock); ReleaseReadLock(&afs_bufferLock); return code; } tb->dirty = 0; } ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); return 0; }
void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs ¶meters) const { assert (inputLength <= MaxUnpaddedLength(oaepBlockLen)); // convert from bit length to byte length if (oaepBlockLen % 8 != 0) { oaepBlock[0] = 0; oaepBlock++; } oaepBlockLen /= 8; std::auto_ptr<HashTransformation> pHash(NewHash()); const size_t hLen = pHash->DigestSize(); const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; byte *const maskedSeed = oaepBlock; byte *const maskedDB = oaepBlock+seedLen; ConstByteArrayParameter encodingParameters; parameters.GetValue(Name::EncodingParameters(), encodingParameters); // DB = pHash || 00 ... || 01 || M pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()); memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); maskedDB[dbLen-inputLength-1] = 0x01; memcpy(maskedDB+dbLen-inputLength, input, inputLength); rng.GenerateBlock(maskedSeed, seedLen); std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF()); pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); }
/*! * \brief Get a pointer to a particular buffer. */ static char * DRead(struct ubik_trans *atrans, afs_int32 fid, int page) { /* Read a page from the disk. */ struct buffer *tb, *lastbuffer, *found_tb = NULL; afs_int32 code; struct ubik_dbase *dbase = atrans->dbase; calls++; lastbuffer = LruBuffer->lru_prev; /* Skip for write transactions for a clean page - this may not be the right page to use */ if (MatchBuffer(lastbuffer, page, fid, atrans) && (atrans->type == UBIK_READTRANS || lastbuffer->dirty)) { tb = lastbuffer; tb->lockers++; lastb++; return tb->data; } for (tb = phTable[pHash(page)]; tb; tb = tb->hashNext) { if (MatchBuffer(tb, page, fid, atrans)) { if (tb->dirty || atrans->type == UBIK_READTRANS) { found_tb = tb; break; } /* Remember this clean page - we might use it */ found_tb = tb; } } /* For a write transaction, use a matching clean page if no dirty one was found */ if (found_tb) { Dmru(found_tb); found_tb->lockers++; return found_tb->data; } /* can't find it */ tb = newslot(dbase, fid, page); if (!tb) return 0; memset(tb->data, 0, UBIK_PAGESIZE); tb->lockers++; code = (*dbase->read) (dbase, fid, tb->data, page * UBIK_PAGESIZE, UBIK_PAGESIZE); if (code < 0) { tb->file = BADFID; Dlru(tb); tb->lockers--; ubik_print("Ubik: Error reading database file: errno=%d\n", errno); return 0; } ios++; /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ return tb->data; }
/** * Invalidate any buffers that are duplicates of abuf. Duplicate buffers * can appear if a read transaction reads a page that is dirty, then that * dirty page is synced. The read transaction will skip over the dirty page, * and create a new buffer, and when the dirty page is synced, it will be * identical (except for contents) to the read-transaction buffer. */ static void DedupBuffer(struct buffer *abuf) { struct buffer *tb; for (tb = phTable[pHash(abuf->page)]; tb; tb = tb->hashNext) { if (tb->page == abuf->page && tb != abuf && tb->file == abuf->file && tb->dbase == abuf->dbase) { tb->file = BADFID; Dlru(tb); } } }
void DZap(afs_int32 *fid) { /* Destroy all buffers pertaining to a particular fid. */ struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(fid)]; tb; tb = tb->hashNext) if (FidEq(tb->fid, fid)) { ObtainWriteLock(&tb->lock); FidZap(tb->fid); tb->dirty = 0; ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); }
void DZap(dir_file_t dir) { /* Destroy all buffers pertaining to a particular fid. */ struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(dir)]; tb; tb = tb->hashNext) if (FidEq(bufferDir(tb), dir)) { ObtainWriteLock(&tb->lock); FidZap(bufferDir(tb)); tb->dirty = 0; ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); }
/*! * \brief Get a pointer to a particular buffer. */ static char * DRead(struct ubik_trans *atrans, afs_int32 fid, int page) { /* Read a page from the disk. */ struct buffer *tb, *lastbuffer; afs_int32 code; struct ubik_dbase *dbase = atrans->dbase; calls++; lastbuffer = LruBuffer->lru_prev; if (MatchBuffer(lastbuffer, page, fid, atrans)) { tb = lastbuffer; tb->lockers++; lastb++; return tb->data; } for (tb = phTable[pHash(page)]; tb; tb = tb->hashNext) { if (MatchBuffer(tb, page, fid, atrans)) { Dmru(tb); tb->lockers++; return tb->data; } } /* can't find it */ tb = newslot(dbase, fid, page); if (!tb) return 0; memset(tb->data, 0, UBIK_PAGESIZE); tb->lockers++; code = (*dbase->read) (dbase, fid, tb->data, page * UBIK_PAGESIZE, UBIK_PAGESIZE); if (code < 0) { tb->file = BADFID; Dlru(tb); tb->lockers--; ubik_print("Ubik: Error reading database file: errno=%d\n", errno); return 0; } ios++; /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ return tb->data; }
/*! * Zap one dcache entry: destroy one FID's buffers. * * 1/1/91 - I've modified the hash function to take the page as well * as the *fid, so that lookup will be a bit faster. That presents some * difficulties for Zap, which now has to have some knowledge of the nature * of the hash function. Oh well. This should use the list traversal * method of DRead... * * \param adc The dcache entry to be zapped. */ void DZap(struct dcache *adc) { int i; /* Destroy all buffers pertaining to a particular fid. */ struct buffer *tb; AFS_STATCNT(DZap); ObtainReadLock(&afs_bufferLock); for (i = 0; i <= PHPAGEMASK; i++) for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext) if (tb->fid == adc->index) { ObtainWriteLock(&tb->lock, 262); tb->fid = NULLIDX; afs_reset_inode(&tb->inode); tb->dirty = 0; ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); }
static CString getCertificateHash(HCRYPTPROV hCryptProv, ALG_ID algId, BYTE* certificate, size_t len) { CString readable = _T("unknown"); std::unique_ptr<BYTE[]> pHash(nullptr); HCRYPTHASH hHash = NULL; if (!hCryptProv) goto finish; if (!CryptCreateHash(hCryptProv, algId, 0, 0, &hHash)) goto finish; if (!CryptHashData(hHash, certificate, (DWORD)len, 0)) goto finish; DWORD hashLen; DWORD hashLenLen = sizeof(DWORD); if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &hashLenLen, 0)) goto finish; pHash.reset(new BYTE[hashLen]); if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash.get(), &hashLen, 0)) goto finish; readable.Empty(); for (const BYTE* it = pHash.get(); it < pHash.get() + hashLen; ++it) { CString tmp; tmp.Format(L"%02X", *it); if (!readable.IsEmpty()) readable += L":"; readable += tmp; } finish: if (hHash) CryptDestroyHash(hHash); return readable; }
/*! * \brief Move this page into the correct hash bucket. */ static int FixupBucket(struct buffer *ap) { struct buffer **lp, *tp; int i; /* first try to get it out of its current hash bucket, in which it might not be */ i = ap->hashIndex; lp = &phTable[i]; for (tp = *lp; tp; tp = tp->hashNext) { if (tp == ap) { *lp = tp->hashNext; break; } lp = &tp->hashNext; } /* now figure the new hash bucket */ i = pHash(ap->page); ap->hashIndex = i; /* remember where we are for deletion */ ap->hashNext = phTable[i]; /* add us to the list */ phTable[i] = ap; return 0; }
static void FixupBucket(struct buffer *ap) { struct buffer **lp, *tp; int i; /* first try to get it out of its current hash bucket, in which it * might not be */ AFS_STATCNT(FixupBucket); i = ap->hashIndex; lp = &phTable[i]; for (tp = *lp; tp; tp = tp->hashNext) { if (tp == ap) { *lp = tp->hashNext; break; } lp = &tp->hashNext; } /* now figure the new hash bucket */ i = pHash(ap->fid, ap->page); ap->hashIndex = i; /* remember where we are for deletion */ ap->hashNext = phTable[i]; /* add us to the list */ phTable[i] = ap; /* at the front, since it's LRU */ }
void DFlushDCache(struct dcache *adc) { int i; struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (i = 0; i <= PHPAGEMASK; i++) for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext) if (tb->fid == adc->index) { ObtainWriteLock(&tb->lock, 701); tb->lockers++; ReleaseReadLock(&afs_bufferLock); if (tb->dirty) { DFlushBuffer(tb); } tb->lockers--; ReleaseWriteLock(&tb->lock); ObtainReadLock(&afs_bufferLock); } ReleaseReadLock(&afs_bufferLock); }
int DRead(struct dcache *adc, int page, struct DirBuffer *entry) { /* Read a page from the disk. */ struct buffer *tb, *tb2; struct osi_file *tfile; int code; AFS_STATCNT(DRead); memset(entry, 0, sizeof(struct DirBuffer)); ObtainWriteLock(&afs_bufferLock, 256); #define bufmatch(tb) (tb->page == page && tb->fid == adc->index) #define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);} /* this apparently-complicated-looking code is simply an example of * a little bit of loop unrolling, and is a standard linked-list * traversal trick. It saves a few assignments at the the expense * of larger code size. This could be simplified by better use of * macros. */ if ((tb = phTable[pHash(adc->index, page)])) { if (bufmatch(tb)) { ObtainWriteLock(&tb->lock, 257); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; } else { struct buffer **bufhead; bufhead = &(phTable[pHash(adc->index, page)]); while ((tb2 = tb->hashNext)) { if (bufmatch(tb2)) { buf_Front(bufhead, tb, tb2); ObtainWriteLock(&tb2->lock, 258); tb2->lockers++; ReleaseWriteLock(&afs_bufferLock); tb2->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb2->lock); entry->buffer = tb2; entry->data = tb2->data; return 0; } if ((tb = tb2->hashNext)) { if (bufmatch(tb)) { buf_Front(bufhead, tb2, tb); ObtainWriteLock(&tb->lock, 259); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = timecounter++; AFS_STATS(afs_stats_cmperf.bufHits++); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; } } else break; } } } else tb2 = NULL; AFS_STATS(afs_stats_cmperf.bufMisses++); /* can't find it */ /* The last thing we looked at was either tb or tb2 (or nothing). That * is at least the oldest buffer on one particular hash chain, so it's * a pretty good place to start looking for the truly oldest buffer. */ tb = afs_newslot(adc, page, (tb ? tb : tb2)); if (!tb) { ReleaseWriteLock(&afs_bufferLock); return EIO; } ObtainWriteLock(&tb->lock, 260); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) { tb->fid = NULLIDX; afs_reset_inode(&tb->inode); tb->lockers--; ReleaseWriteLock(&tb->lock); return EIO; } tfile = afs_CFileOpen(&adc->f.inode); code = afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data, AFS_BUFFER_PAGESIZE); afs_CFileClose(tfile); if (code < AFS_BUFFER_PAGESIZE) { tb->fid = NULLIDX; afs_reset_inode(&tb->inode); tb->lockers--; ReleaseWriteLock(&tb->lock); return EIO; } /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; }
/** * read a page out of a directory object. * * @param[in] fid directory object fid * @param[in] page page in hash table to be read * * @return pointer to requested page in directory cache * @retval NULL read failed */ void * DRead(afs_int32 *fid, int page) { /* Read a page from the disk. */ struct buffer *tb, *tb2, **bufhead; ObtainWriteLock(&afs_bufferLock); calls++; #define bufmatch(tb) (tb->page == page && FidEq(tb->fid, fid)) #define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);} /* this apparently-complicated-looking code is simply an example of * a little bit of loop unrolling, and is a standard linked-list * traversal trick. It saves a few assignments at the the expense * of larger code size. This could be simplified by better use of * macros. With the use of these LRU queues, the old one-cache is * probably obsolete. */ if ((tb = phTable[pHash(fid)])) { /* ASSMT HERE */ if (bufmatch(tb)) { ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } else { bufhead = &(phTable[pHash(fid)]); while ((tb2 = tb->hashNext)) { if (bufmatch(tb2)) { buf_Front(bufhead, tb, tb2); ObtainWriteLock(&tb2->lock); tb2->lockers++; ReleaseWriteLock(&afs_bufferLock); tb2->accesstime = ++timecounter; ReleaseWriteLock(&tb2->lock); return tb2->data; } if ((tb = tb2->hashNext)) { /* ASSIGNMENT HERE! */ if (bufmatch(tb)) { buf_Front(bufhead, tb2, tb); ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } } else break; } } } else tb2 = NULL; /* can't find it */ /* The last thing we looked at was either tb or tb2 (or nothing). That * is at least the oldest buffer on one particular hash chain, so it's * a pretty good place to start looking for the truly oldest buffer. */ tb = newslot(fid, page, (tb ? tb : tb2)); ios++; ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); if (ReallyRead(tb->fid, tb->page, tb->data)) { tb->lockers--; FidZap(tb->fid); /* disaster */ ReleaseWriteLock(&tb->lock); return 0; } /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ ReleaseWriteLock(&tb->lock); return tb->data; }