crypto class design

Leichter, Jerry leichter_jerrold at emc.com
Wed Dec 19 09:40:33 EST 2007


| So... supposing I was going to design a crypto library for use within
| a financial organization, which mostly deals with credit card numbers
| and bank accounts, and wanted to create an API for use by developers,
| does anyone have any advice on it?
| 
| It doesn't have to be terribly complete, but it does have to be
| relatively easy to use correctly (i.e. securely).
| 
| I was thinking of something like this:
| 
| class crypto_api
| {
|     ...
|     // developers call these based on what they're trying to do
|     // these routines simply call crypto_logic layer
|     Buffer encrypt_credit_card(Buffer credit_card_number, key_t key);
|     Buffer encrypt_bank_account(Buffer bank_account, key_t key);
|     Buffer encrypt_other(Buffer buffer, key_t key);
|     ...
| };
| 
| class crypto_logic
| {
|     ...
|     algo_default = ALGO_AES256CBC;
|     // encrypt with a given algorithm
|     Buffer encrypt(Buffer buffer, key_t key, algo_t aid = algo_default);
|     // calls different routines in crypto_implementation layer depending on algorithm used
|     Buffer decrypt(Buffer buffer, key_t key);
|     ...
| };
| 
| class crypto_glue
| {
|     ...
|     // calls routines in libraries such as OpenSSL
|     // mostly wrappers that translate between our data types and theirs
|     Buffer aes256cbc-encrypt(...);
|     Buffer aes256cbc-decrypt(...);
|     ...
| };
| 
| The general idea is that crypto_api provides domain-specific APIs that
| are easy for anyone to understand, that the logic layer allows for the
| selection of different algorithms, and the glue layer is basically a
| translation layer to underlying libraries.
| 
| It is very important that the API remain stable, because the code
| base is large and owned by various groups.
| 
| One thing that I'm wondering is how to indicate (e.g.) the overhead in
| terms of padding, or whatever, for various algorithms... or if it
| matters.  The old code had some really disturbing practices like
| assuming that the output buffer was 16 octets bigger, and stuff like
| that... scary.
| 
| Intend to skim the OpenSSL design and Gutmann's "Design of a
| Cryptographic Security Architecture" for ideas.
| 
| Comments?
Your Buffer class is a step up from using a void*!  You're not really
using data typing effectively.  Define classes to encapsulate encrypted
and cleartext data; carefully decide what transitions are allowed among
them; and define your API around that.  Note that transitions include
creation and, particularly, deletion - the destructor for cleartext
should zero the memory.

The above is a simplification.  There are probably more than two
categories of data.  A better classification might be:  Encrypted,
cleartext but sensitive, non-sensitive.  In a financial setting,
"sensitive" may have subdivisions based, for example, on who is allowed
access.  Should there be some special datatype for keys, which are about
the most sensitive thing in the system?  (It should probably be the case
that the common public API's provide no way to export a key, just a way
to apply it.  Key management should be a separate API that most
applications don't even use, so you can be sure they can't (without
cheating, which is of course always possible in C++) leak them.)

As much as possible, make the actual rules that apply to any piece of
data in the program (a) transparent to someone reading the code; (b)
enforceable by a compiler or, second best, the API implementation.  In
the public API, concentrate on the data and the rules that govern it.
Particular crypto algorithms and various related choices should be
hidden within the implementation.  Not only should the API be easy to
use correctly, it should be as hard as possible to use *in*correctly!

							-- Jerry

---------------------------------------------------------------------
The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majordomo at metzdowd.com



More information about the cryptography mailing list