On Tue, Feb 17, 2009 at 12:49 PM, sofian sindhi <sofiansis...@gmail.com> wrote:
> Dear all:
> I trace openssl recently and I cannot find where the location of EVP_CIPHERs
> defined in evp.h.
> In evp.h, it is declared as const EVP_CIPHER *EVP_camellia_128_ecb(void);
> But where is the trully EVP_camellia_128_ecb(void) located?
> I have grepped the source but I cannot get any hint.

In your question you are mixing up two things: EVP_CIPHER is a data
structure type (used to carry around cipher context needed by the user
& the cipher to perform the task in multiple phases while the data is
fed piecemeal to the system at the same time).

grep EVP_CIPHER -->
ossl_typ.h:
typedef struct evp_cipher_st EVP_CIPHER;
--> grep "struct evp_cipher_st" -->
evp.h:
struct evp_cipher_st { ...... };

(which, incidentally, also has /* EVP_CIPHER */ as a comment/hint at
the end, so we are heartened in knowing we've hit the jackpot there)


When, instead, you want to find where the _function_
EVP_camellia_128_ecb() is defined in the code, and, as you found,
cannot track it's definition down using grep (regular text search),
then you can go about it various ways, but the oldest and most sure
way is this:

when you are in such a situation (and otherwise ;-) ), remember that
'C' also comes with a *preprocessor*.
That one is used to conditionally include / exclude chunks of source
code at compile time, but also offers 'macro' functionality, which in
the 'C' realm, can be used to implement something similar to
'templates' (as we know them in, for example, 'C++'.     FYI: OpenSSL
uses this possibility to great effect in various spots (EVP & ASN1
most particularly).
Nothing fancy or difficult, it's just that people tend to forget or,
more often, never got taught the language properly (and then complain
about others' lack of minding their forgetfulness :-) ). No worries,
it's just got to be my Grumpy Day today. ;-)

So, can't find a function or data definition anywhere?

Here's the general process of digging them up:
Run the code through the *preprocessor* and then have a grep through
that (intermediate) output. (After all, all the preprocessor does is
munch source code and spit out 'preprocessed' *source code* for the
actual *compiler*.

(Almost) all compilers (and at least ALL the ones I've met in
non-embedded environments) offer an option to do exactly that:
generally, this is command line option '-E' (~ 'execute preprocessing
phase only').
for example:
gcc has '-E'
MSVC cl has '-E' and '-EP'

the hard(er) part is getting the '-E' option added to your compiler
commandline argument set (easy on most systems by temporarily
redefining GCC or CC environment args so that
CC='gcc -E'
instead of
CC='gcc'
but this can cause some trouble in your makefiles as they won't expect
this, but alas, you're interested in preprocessed sourcecode there
now, not working executables, so ignore the alarm bells and let it
rip.

Most systems will write such -E preprocessed output to either a .i
file (<sourcefilename>.i, e.g. apps.c --> apps.i) or the .o or .obj
file if such a target was specified explicitly on the commandline
using '-o'. There's no 'always so' rule to this bit, hence me saying
it's 'harder', meaning: you must check how it acts on your system and
environment, whichever it is.

The alternative is running your suspects through 'gcc -E' or your
local equivalent *by hand*. ( = copy&paste commandlines issued from
make, add the -E yourself and have a go.)


The second alternative, when '-E' is not available or otherwise
unwilling to cooperate, is to trace the code using a source-viewing
debugger: as you run through the code you will notice that function
calls will instead sometimes show macro invocations outside any
function scope. That's a sure sign there's some templating / code
generation going on under the hood right there.
--> from there, find those macro definitions and inspect their source
code. Further drilldown takes a tool like grep again.




So far, Preprocessor Ed 102. (Giving you just the result is pretty
useless; the above is needed to enable you to reproduce the result and
answer subsequent, similar questions on your own.)

The result of this search will find you EVP_camellia_128_ecb() here:

evp_locl.h:
const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
which is a function returning the static/const structure defining the
cipher and its requirements, such as block length, IV size, ASN.1
aspects such as object ID (nid), plus: the functions (in object/class
oriented terms that would be 'methods' rather) used to perform the
action on chunks of data (cname##_##mode##_cipher), cleanup the
EVP_CIPHER object when you're done (cleanup), etc.

When you follow the preprocessor (i.e. answer the question: "how did
this bit get expanded into that EVP_camellia_128_ecb() we were looking
for?"), you'll find it starts here:

e_camellia.c:
IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY, .......

which is defined here:
evp_locl.h:
#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
....

and the part of that macro which leads us further is this bit in there:

        BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \

as that expands, thanks to the definition here:

evp_locl.h:
#define BLOCK_CIPHER_defs(cname, kstruct, \
   ....

via this macro's bit:
... \
BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
......

via

evp_locl.h:
#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
...
-->
BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
...

via

#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
...
*** BINGO! ***
...
const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }



Granted, first time around, this may give you a headache, unless
you're like me and wondered, after reading the C language specs
(before starting to code), where one would use the ## operator to good
effect in daily practice, and then discover to your extreme joy a
piece of code where this is used to create 'code templates' in C, very
much like what we have today as templates in C++. The code which got
me that happy[*] is long gone (something written close to 20 years ago
by a man named Sim Yskes for Shell), but here is another prime
example.

[*] finally, I _learned_ something, instead of hearing the IT
equivalent again of chewing gum fixing gas tank leaks as they already
did way back in WWII. Apparently, software in peace time is not
expected to live any longer than Spitfires in war time, but I digress.



For your edification:

Another very nice use of this ability to make code manageable yet
concise (and, yes, we expect one has received (and picked up) an
education other than primary school alone when going to work on this
sort of thing) is the typechecking safestack template code (see
<safestack.h> which wraps compile typechecking around the generic core
functionality in <stack.h>; C++ coders would, today, do exactly the
same using templates. So would Java coders or anybody else who's got a
(strictly typed) language with built-in template ability and a
need/want for strict type checking.
This <safestack> is a very simple use of macros this way, so this bit
of code is preferable to read when you're learning this kind of thing
for the first time.

When you 'grok' (understand) how the macros in <safestack.h> provide
this compile-time typechecking ability, you can take it up to the next
level and either 'read' the EVP macros in evp_locl.h and see how they
are used, or better (because the format is a general standard so you
can read up anywhere about what it should do, so you can think about
how you'd do it and see how the OpenSSL creators have solved this
problem) read the ASN.1 code, which is another example of typesafe
template code [generation] in C, just like EVP.
(for ASN.1 study, start at the ans1parse.c code, from there it'll take
you to tasn_typ.c and asn1t.h, among others.)
(for EVP study, start at apps/enc.c, which will lead you to evp_enc.c
and consequently, evp.h and evp_locl.h.)



TIP: the MSVC IDE has a nice feature, which works once you use project
files for this stuff (available at hebbut.net, for example): click on
a function or type, right-click -> 'Go to definition' and it jumps to
the line and sourcefile where it believes that bit has been defined.
(Same for declarations, by the way.) It's not a 'sure thing' as the
IDE can be easily misled, but generally, when it lands on such a macro
instead of the name proper, it takes only a little thought and further
drilldown using right-click->"go to definition", to find where the
structure or function name is constructed from its parts, using ##.
That is, at least, how I did it while writing this. ;-)  (grep works
too, but I'm lazy and this is just a tad faster)





I wrote this in hopes I only need to write it once, as others arriving
at that same junction where you are: "where the heck is that function
gone now?!" will read this and know what to do next after all. Some
stuff requires a longer answer to really get you something. (And next
time, I can refer back. Saves me the trouble of typing tomorrow.)
The key to it all is standard C 'preprocessor parameter concatenation'
a.k.a. ## (plus students reading language (grammar) specifications
instead of having to stumble forward by trial & error as they receive
'practice-oriented' ed).

-- 
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to