Key Generation Functions
Prev | Chapter 7. Support Function Reference | Next

## Key Generation Functions

Atheros applications use the SHA256 algorithm to compute unique HomePlug AV keys, including the Device Access Key (DAK), Network Membership Key (NMK) and Network Identifier (NID). The SHA256 algorithm is seeded, salted and rehashed differently for each type of HomePlug AV key. A different function is used to compute each type of HomePlug AV key but all of them call the SHA256 functions. The SHA256 algorithm returns a `256` bit (`32` byte) digest but only the upper `128` bits (`16` bytes) are used for HomePlug AV keys.

Example 7.3. SHA256 Digest Computation

The following code example illustrates how to generate, rehash and print an SHA256 digest, or key, from a user-defined seed string and salt string. This logic is typical of that used to generate HomePlug AV compliant keys. See the HomePlug AV Specification for the specific rules used to generate each type of key.

    #include <stdio.h>

    #include "../crypt/SHA256.h"

    #include "../crypt/SHA256Reset.c"
    #include "../crypt/SHA256Block.c"
    #include "../crypt/SHA256Write.c"
    #include "../crypt/SHA256Fetch.c"

    struct sha256 sha256;
    char * seed = "ForMeToKnowAndYouToFindOut";
    char * salt = "X$z@p";
    byte digest [SHA256_DIGEST_SIZE];
    int i;

    SHA256Reset (&sha256);
    SHA256Write (&sha256, (byte *)(seed), strlen (seed));
    SHA256Write (&sha256, (byte *)(salt), strlen (salt));
    SHA256Fetch (&sha256, digest);

    for (i = 0; i < 999; i++)
    {
    	SHA256Reset (&sha256);
    	SHA256Write (&sha256, digest, sizeof (digest));
    	SHA256Fetch (&sha256, digest);
    }
    for (i = 0;  i < 16; i++)
    {
    	printf ("%02x", digest [i]);
    }
    printf ("\n");

Above, we declare struct `sha256` and initialize it using function SHA256Reset. We then write a user-defined seed string (or password) followed by an optional salt string to the digest using function SHA256Write. The resulting digest (or key) is obtained by calling function SHA256Fetch. Constant `SHA256_DIGEST_SIZE` is defined in SHA256.h. Although the digest is probably secure enough at this point, we rehash it `999` times for good measure. We then print the first `16` bytes of the result because HomePlug AV keys are always `16` bytes long.

### MACPasswords

`void MACPasswords(` | vendor, |
| device, |
| number, |
| count, |
| bunch, |
| space, |
| flags`)`; |

`uint32_tvendor`;
`uint32_tdevice`;
`uint32_tnumber`;
`unsigned count`;
`unsigned bunch`;
`unsigned space`;
`flag_t flags`;

Print a range of device addresses and user passwords on stdout. The calling application must split the starting device address into a three-byte OUI and three-byte device number and pass them as the unsigned 32-bit integers `vendor` and `device`, respectively. Argument `device` is the first device number in the range and `number` is the final device number. Argument `count` is the number of uppercase letters comprising a password. Passwords contain this many letters but the letters are grouped for easy reading. Letter groups are separated by hyphens. Argument `bunch` defines how many letters form each group. Argument `space` is the character used to separate groups of letters. Argument `flags` enables or disables function features such as insertion of a “used” flag for use by the Atheros Production Test System or the omission of the device address on output. The output of this function is similar to that produced by the DB Builder utility distributed with the PTS. This function is declared in keys.h and defined in MACPasswords.c.

### HPAVKeyDAK

`void HPAVKeyDAK(` | DAK, |
| string`)`; |

`byte DAK []`;
`char const string`;

Encode buffer `DAK` with the Device Access Key (DAK) derived from the `NUL` terminated `string`. The `string` is salted, hashed and re-hashed using the SHA256 algorithm. The `DAK` is always `HPAVKEY_DAK_LEN` bytes, defined in HPAVKey.h, so no length argument is needed. See the HomePlug AV Specification for more information. This function is declared in HPAVKey.h and defined in HPAVKeyDAK.c.

### HPAVKeyNMK

`void HPAVKeyNMK(` | digest, |
| string`)`; |

`byte digest []`;
`char const string`;

Encode buffer `NMK` with the Network Membership Key (NMK) derived from the `NUL` terminated `string`. The string is salted, hashed and re-hashed using the SHA256 algorithm. The `DAK` is always `HPAVKEY_NMK_LEN` bytes, as defined in HPAVKey.h, so no length argument is needed. See the HomePlug AV Specification for more information. This function is declared in HPAVKey.h and defined in HPAVKeyNMK.c.

### HPAVKeyNID

`void HPAVKeyNID(` | NID, |
| NMK, |
| level`)`; |

`byte NID []`;
`byte const NMK []`;
`signed level`;

Encode buffer `NID` with the Network Identification Key (NID) derived from the 16-byte Network Membership Key (NMK). The `NMK` is hashed and re-hashed using the SHA256 algorithm then encoded with the security `level`. The `NID` is always `HPAVKEY_NID_LEN` bytes, as defined in HPAVKey.h, so no length argument is needed. See the HomePlug AV Specification for more information. This function is declared in HPAVKey.h and defined in HPAVKeyNID.c.

### HPAVKeyOut

`void HPAVKeyOut(` | digest, |
| length, |
| phrase, |
| flags`)`; |

`byte const digest []`;
`size_t length`;
`char const * phrase`;
`flag_t flags`;

Decode and print up to `length` bytes from buffer `digest` on stdout. Print `NUL` terminated `phrase` on the same line following the digest when bit `HPAVKEY_VERBOSE`, defined in HPAVKey.h, is set in `flags`. This procedure prints keys and phrases in a standard column-oriented format that other applications can easily read and use. This function is declared in HPAVKey.h and defined in HPAVKeyOut.c.

### SHA256Block

`void SHA256Block(` | sha256, |
| memory`)`; |

`struct sha256 * sha256`;
`void const * memory`;

Merge 64 bytes of memory into the current SHA256 digest. This function performs the core computations required by the SHA256 algoithm. It is called by function `SHA256Fetch` and so there is no reason to call this function directly. The `sha256` structure is defined in SHA256.h. The function is declared in SHA256.h and defined in SHA256Block.c.

### SHA256Fetch

`void SHA256Fetch(` | sha256, |
| digest`)`; |

`struct sha256 * sha256`;
`byte digest []`;

Conclude SHA256 computation and transfer the result to the named 32-byte `digest` then flush the `sha256` structure. The `digest` is always 32 bytes long regardless of the amount of information that has been written using function SHA256Write. The `sha256` structure is defined in SHA256.h. This function is declared in SHA256.h and defined in SHA256Fetch.c.

Once this function is called, the `sha256` structure is purged for security reasons. You must call SHA256Reset again before starting another hash or subsequent calls to this function or SHA256Write will have unpredictable results. .

### SHA256Ident

`void SHA256Ident(` | fd, |
| digest`)`; |

`int fd`;
`byte digest []`;

Compute the SHA256 digest from the content of a file. The digest serves as the file “fingerprint” and can be used to identify identical content despite filename changes. File descriptor `fd` is the subject file which must be positioned to the start befor calling this function. Buffer `digest` will be written with the computed 256-digest and must be `SHA256_DIGEST_SIZE` bytes long, as defined in SHA256.h. This function is declared in SHA256.h and defined in SHA256Ident.c.

### SHA256Match

`void SHA256Match(` | fd, |
| digest`)`; |

`int fd`;
`byte const digest []`;

Search a registry file for a known SHA256 digest. Return `true` on success or `false` on failure. File descriptor `fd` is the registry file which must be positioned to the start before calling this function. Buffer `digest` contains the known 256-bit digest and must be `SHA256_DIGEST_SIZE` bytes long, as defined in SHA256.h. A registry file consists of 64-digit hexadecimal strings that represent SHA256 digest values. Optional text may be appear between the digest and newline to document digest significance. This function ignores such text. This function is declared in SHA256.h and defined in SHA256Match.c.

### SHA256Print

`void SHA256Print(` | digest, |
| string`)`; |

`byte const digest []`;
`char const * string`;

Print an SHA256 `digest` and optional `string` on `stdout`. Buffer `digest` must be `SHA256_DIGEST_SIZE` bytes long, as defined in SHA256.h, which results in 64 hexadecimal digits on output. Variable length string is `NUL` terminated but may be `NULL`. If `string` is not `NULL` and is not empty then a space is inserted between the digest and the string on output. This function may be used to print SHA256 digests and optional strings in standard format, such as a registry file. This function is declared in SHA256.h and defined in SHA256Print.c.

### SHA256Reset

`void SHA256Reset(` | sha256`)`; |

`struct sha256 * sha256`;

Initialize a `sha256` structure before computing a new SHA256 digest. This function should be called once before calling SHA256Write for the first time for a given digest. The `sha256` structure is defined in SHA256.h. This function is declared in SHA256.h and defined in SHA256Reset.c.

### SHA256Write

`void SHA256Write(` | sha256, |
| memory, |
| extent`)`; |

`struct sha256 * sha256`;
`void const * memory`;
`size_t extent`;

Writes a region of memory to the current SHA256 digest contained in an `sha256` structure. An application may call this function any number of times to concatinate multiple memory regions before fetching the digest with function `SHA256Fetch`. The `sha256` structure is defined in SHA256.h. This function is declared in SHA256.h and defined in SHA256Write.c.

Prev | Up | Next
Message Debug Functions | Home | XML Editing Functions