Re: c>c++ code translation

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



See below...
On Fri, 10 Nov 2006 15:42:01 -0800, segue <segue@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:


Can someone explain what this class could be doing I don't know C++.

Thanks

void CRequest::OnSpawn() {
CString str;
SelectTransactionProcessor(""); // Selects default transaction processor
srand((unsigned)time(NULL));
****
This is seeding the random number generator with the current time so that you get a
"random" pattern to what is happening
****
for (int i=0; i<47; i++,rand()) {};
****
This statement is nonsensical and should be removed; it was written by someone who is
totally clueless. It generates 47 random numbers. This serves no useful purpose.
****
KeyL=(rand()<<16)+rand();
KeyM=(rand()<<16)+rand();
****
This is a pathethic attempt to create 32-bit "random" numbers. It is crap. It is based
on some erroneous premises about the rand() generator and will not really generate good
32-bit random numbers. I'm appending my 32-bit random number generator at the end.
****
str.Format("220
%08x%08x%04x%04x%04x%04x%04x%04x%04x%04x\r\n",KeyL,KeyM,rand(),rand(),rand(),rand(),rand(),rand(),rand(),rand());
(*this) << str.GetBuffer(0);
****
This was written by someone totally clueless. It pretends to format some kind of "random"
key, but it is nonsense because it still uses a crappy random number generator. Then it
calls GetBuffer() and fails to release the buffer. I would say that the author of this
whole piece of code is deeply clueless about both random numbers and MFC. And judging from
the "(*this)<<" it suggests the person might be clueless about C++ and modularization as
well. So it is not surprising it is hard to read. The correct solution in this case is
to throw it out and rewrite it. The goal is to generate (if I've counted right) a
192-bit (24-byte) random number. This will not actually do that. It will generate a
192-bit value, but its randomness is problematic.
****
TicksTillDisconnect=600;
****
Seems unrelated to generating a random number. So either the random number generator
should have been a separate method called from this code or this code should not be doing
other things.
****
}

*****
Here's my 32-bit random number generator. See the comment below; it trivially generalizes
to handle wider values, you just need to tweak the code a bit.

This is essentially implemented as a singleton class, and to get a random number I call

int n = Rand32::rand32();

The reason I did my own GetLastError handler had to do with meeting some existing
contraints; I would be more likely to ::SetLastError myself if I reused this code.
*****
//========================= RAND32.H ===========================
#pragma once
#include <WinCrypt.h>

class Rand32 {
public:
typedef enum {None, Crypto, Fake} RandType;

static RandType GetRandType();
static int rand32();
static GetLastError() { return error; }
protected:
static HCRYPTPROV provider;
static __declspec(thread) DWORD error;

};


//======================== RAND32.CPP ==========================
#include "stdafx.h"
#include "rand32.h"
#include <WinCrypt.h>

// This is not really a "random" number, and this code should ideally never
// be executed. I put it in as a fallback in case something really screws up
#define RAND32() ((int)(((DWORD)rand() << 17) ^ ((DWORD)rand() << 9) ^ rand()))

/* protected: static */ HCRYPTPROV Rand32::provider = NULL;

__declspec(thread) DWORD Rand32::error = 0;

/****************************************************************************
* rand32
* Result: int
* A 32-bit random number
* Notes:
* Sets ERROR_SUCCESS if successful
****************************************************************************/

/* static */ int Rand32::rand32()
{
error = ERROR_SUCCESS;

if(provider == NULL)
{ /* get provider */
if(!::CryptAcquireContext(&provider,
NULL, // use default cryptographic container
NULL, // use default cryptographic provider
PROV_RSA_FULL, // as good a choice as any
CRYPT_NEWKEYSET | CRYPT_SILENT))
{ /* failed */
error = ::GetLastError();
provider = (HCRYPTPROV)INVALID_HANDLE_VALUE;
} /* failed */
} /* get provider */

if(provider != (HCRYPTPROV)INVALID_HANDLE_VALUE)
{ /* get number */
int result;

if(::CryptGenRandom(provider, sizeof(int), (LPBYTE)&result))
return result;
// *****************
// Note here that if you define
// #define RAND_BYTES 24
// then you can use this same code to generate the entire
// 24-byte random number in a single call!
// if(::CryptGenRandom(provider, RAND_BYTES, (LPBYTE)buffer)
// where buffer is
// BYTE buffer[RAND_BYTES];
// and making other suitable changes in the code as needed, then
// you will have very good random number generator
//
// I forget who first pointed me at this solution, but thanks to whomever that was
..//*******************

error = ::GetLastError();
::CryptReleaseContext(provider, 0); // failed, why?
provider = (HCRYPTPROV)INVALID_HANDLE_VALUE;
} /* get number */

return RAND32();

} // rand32


/****************************************************************************
* GetRandType
* Result: RandType
* Type of random number returned
****************************************************************************/

/* static */ Rand32::RandType Rand32::GetRandType()
{
if(provider == NULL)
return None;
if(provider == (HCRYPTPROV)INVALID_HANDLE_VALUE)
return Fake;
return Crypto;
} // GetRandType
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: Comments re ISCs announcement on bind9 security
    ... It's a text published by ISC as a follow up to the bind9 predictable id saga. ... less an issue of using "extremely weak crypto" as it has been ... than the use of a random number generator that did not ... The particular pseudo-random number generator that BIND 9 now uses is a poor ...
    (Bugtraq)
  • Re: Math.random
    ... the number of bits the generator outputs at a time has nothing ... their succession present systematic biases. ... as the design of UUIDs assumes them to be. ... crypto system of all, the Vernam cipher or one-time pad. ...
    (comp.lang.javascript)
  • Re: Security Engineering vs. Crypto Academics... (was strengthening /dev/urandom)
    ... This seems to be a common theme in any generator that's had some thought put ... It's interesting tracing the evolution of these things, PGP ... AFAIK was a Colin Plumb idea (he's influenced an awful lot of RNG design), ... with periodic re-seeding, not relying on a single crypto primitive, etc etc). ...
    (sci.crypt)
  • Re: Initializing GFSR Generators.
    ... >> For Cryptographic work, is it really necessary to have a statisticly ... Then all one needs to do is isolate that state from analysis. ... > The amount of work necessary to isolate a generator that is merely ... Crypto Glossary http://www.ciphersbyritter.com/GLOSSARY.HTM ...
    (sci.crypt)
  • Re: help
    ... we'll skip using a random number generator ... int clamp ... distribution of inputs (i.e. each number in the range occurs exactly ... Given the common uses for random number generators, ...
    (alt.comp.lang.learn.c-cpp)