Stefan Neis wrote:
[...]
No. The functions are there just fine.
_Implementing_ them uses the macros.
So the definition for SHA1_Update is in that file with the
#define HASH_UPDATE SHA1_Update
It just internally uses the macro to implement it.
It somewhat confusing, but you can use your preprocessor
to understand what's going on. Passing a "-E" (or "/E") instead
of "-c" (or "/c") to the command line that compiles the actual
file should give you the preprocessor output, i.e. the code that
the compiler actually gets to see after the macro substitutions
did take place - that might help to understand what's actually
going on...
I second that. Sound advice there!
However, I have a feeling there's a more fundamental issue at hand here.
Therefore I'd like to add something that may sound too trivial to you,
but please bear with me as I think it will benefit you greatly before
you start porting the OpenSSL source code:
please check out Kernighan & Ritchie's book 'C, the programming
language' where you should pay _special_ attention to the chapters
describing
the C preprocessor: that the part we're interested in here anyway.
An English version is available here (translations to other languages
abound):
http://www.amazon.com/C-Programming-Language-2nd-Ed/dp/0131103709/
or you probably already have it somewhere in your bookshelf; please
revisit for the detailed operation of the ANSI C preprocessor.
Before you check out md32_common.h and the crypto/xxx library code you
may try your hand at something simpler to easily recognize the inner
workings (OpenSSL /E output might be a tad daunting at first): create a
project / makefile which compiles 3 C source files to create a Windows
console executable using the code listed at the end (I've got a MSVS2005
project zip available if you like: only 4KB):
If you can explain to yourself clearly what is happening in
fake_common.h and how those fake_MD5() and fake_SHA() functions came to
be, you'll also recognize the way md32_common.h et al do this at a much
grander scale. When you also wish to understand the ASN1 code, see how
these values in the expected output were calculated: 3, 6 and 9.
Bottom line: OpenSSL uses the C preprocessor to templatize the code to
great effect: reduced code size ( less lines means less bugs) & code
reuse (single point to fix bug; no duplications which may be overlooked
during maintenance).
HTH,
Ger
PS: the actual C code here is meant as a preprocessor sample only; the
sample code is littered with some ugly coding practices. It's the stuff
with the # dashes that counts anyway.
---fake_common.h---
/* generic implementation stuff: it's only about recognizing the
workings of the C preproc... */
#ifndef __FAKE_HASH_H__
#define __FAKE_HASH_H__
/*
another bit of preprocessor stuff; important to understand
before you try to understand the ASN1 template code:
*/
#define get_magic(t) call_magic(t)
#define call_magic(t) get_magic_ ## t (3)
int get_magic_MD5(int fact);
int get_magic_SHA(int fact);
int get_magic_FAKE_TYPE(int fact); /* this one is a bit nasty :-) */
/* end of extra bit of stuff */
#define name(f) mkstr(f)
#define mkstr(f) # f
/* overly simplified piece of md32_common.h */
char *FAKE_HASH(void)
{
static char buf[256];
sprintf(buf, "I'm '%s()'! and I give you: %d/%d", name(FAKE_HASH),
get_magic(FAKE_TYPE), call_magic(FAKE_TYPE));
return buf;
}
#endif
----------
---fake_md5.h---
#ifndef __FAKE_MD5_H__
#define __FAKE_MD5_H__
/* prototype only: API */
char *fake_MD5(void);
#endif
----------
---fake_sha.h---
#ifndef __FAKE_SHA_H__
#define __FAKE_SHA_H__
/* prototype only: API */
char *fake_SHA(void);
#endif
----------
---fake_md5.c---
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fake_md5.h" /* not required, but helps development by
prototype validation */
#define FAKE_HASH fake_MD5
#define FAKE_TYPE MD5
#include "fake_common.h"
----------
---fake_sha.c---
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fake_sha.h" /* not required, but helps development by
prototype validation */
#define FAKE_HASH fake_SHA
#define FAKE_TYPE SHA
#include "fake_common.h"
----------
---main.c---
/*
expected output of test program:
calling fake MD5 --> I'm 'fake_MD5()'! and I give you: 3/9
calling fake SHA --> I'm 'fake_SHA()'! and I give you: 6/9
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fake_md5.h"
#include "fake_sha.h"
int main(void)
{
printf("calling fake MD5 --> %s\n", fake_MD5());
printf("calling fake SHA --> %s\n", fake_SHA());
return 0;
}
/* next is only relevant for additional ## sample code in fake_common.h */
int get_magic_MD5(int fact)
{
return 1 * fact;
}
int get_magic_SHA(int fact)
{
return 2 * fact;
}
int get_magic_FAKE_TYPE(int fact)
{
return 3 * fact;
}
----------
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]