📄 crypto.c
字号:
cobj = cobj;
if (outbuf == NULL) {
*outbuflen = buflen;
return RET_OK;
}
if (*outbuflen < buflen) {
*outbuflen = buflen;
return -1;
}
*outbuflen = buflen;
B_COPYSTRINGN (outbuf, buf, buflen);
return RET_OK;
}
INT16
wtls_crypto_decompress (wtls_crypto_t *cobj,
BYTE *buf, UINT16 buflen,
BYTE *outbuf, UINT16 *outbuflen)
{
cobj = cobj;
if (outbuf == NULL) {
*outbuflen = buflen;
return RET_OK;
}
if (*outbuflen < buflen) {
*outbuflen = buflen;
return -1;
}
*outbuflen = buflen;
B_COPYSTRINGN (outbuf, buf, buflen);
return RET_OK;
}
#endif
INT16
wtls_crypto_HMAC_init (wtls_crypto_t *cobj, BYTE *key, UINT16 keylen)
{
BYTE buf1[MAX_HASH_BLOCK_SIZE];
UINT16 i = 0;
if (keylen > cobj->mac_block_size) {
wtls_err_set (ERR_CRYPTLIB, ERR_HASH_KEY_TOO_LONG,
1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
/* Step 0: Copy the key material */
/* Step 1: Append zeros to a length of B bytes */
/* Step 2: XOR with ipad (0x36) */
for (i = 0; i < keylen; i++) {
buf1[i] = key[i] ^ 0x36;
}
for (i = keylen; i < cobj->mac_block_size; i++) {
buf1[i] = 0x36;
}
/* Step 3: Append the data */
/* Step 4: Apply H to the data generated in step 3. */
if ((wtls_crypto_hash_init (cobj) < 0) ||
(wtls_crypto_hash_update (cobj, buf1, cobj->mac_block_size) < 0)) {
return -1;
}
return RET_OK;
}
INT16
wtls_crypto_HMAC_update (wtls_crypto_t *cobj, BYTE *data, UINT16 datalen)
{
if (wtls_crypto_hash_update (cobj, data, datalen) < 0) {
return -1;
}
return RET_OK;
}
INT16
wtls_crypto_HMAC_final (wtls_crypto_t *cobj,
BYTE *key, UINT16 keylen, BYTE *result)
{
BYTE buf1[MAX_HASH_BLOCK_SIZE];
BYTE md[MAX_HASH_MAC_SIZE];
INT16 i;
if (wtls_crypto_hash_final (cobj, md) < 0) {
return -1;
}
/* Step 5: XOR the byte string computed in step 1 with opad (0x5c) */
for (i = 0; i < keylen; i++) {
buf1[i] = key[i] ^ 0x5c;
}
for (i = keylen; i < cobj->mac_block_size; i++) {
buf1[i] = 0x5c;
}
/* Step 6: Append the result from step 4 to the string from step 5 */
/* Step 7: Apply H to the data generated in step 6 */
if ((wtls_crypto_hash_init (cobj) < 0) ||
(wtls_crypto_hash_update (cobj, buf1, cobj->mac_block_size) < 0) ||
(wtls_crypto_hash_update (cobj, md, cobj->full_mac_size) < 0) ||
(wtls_crypto_hash_final (cobj, result) < 0)) {
return -1;
}
return RET_OK;
}
/*
* Compute the Message Authentication Code as described in sections 9.2.3.2
* and 11.3.1 of the WTLS specification.
* The result is placed at the location indicated by 'mac'.
*/
INT16
wtls_crypto_MAC (wtls_crypto_t *cobj, BYTE *mac_secret,
BYTE *buf, UINT16 buflen,
UINT16 seqnum, UINT8 rec_type,
BYTE *mac)
{
BYTE tmpbuf[5];
/* Here we use WTLS spec section 9.2.3.2.
* Concatenate: seqnum + rec_type + buflen + data */
tmpbuf[0] = (seqnum >> 8) & 0xff;
tmpbuf[1] = seqnum & 0xff;
tmpbuf[2] = rec_type;
tmpbuf[3] = (buflen >> 8) & 0xff;
tmpbuf[4] = buflen & 0xff;
if ((wtls_crypto_HMAC_init (cobj, mac_secret, cobj->mac_key_size) < 0) ||
(wtls_crypto_HMAC_update (cobj, tmpbuf, 5) < 0) ||
(wtls_crypto_HMAC_update (cobj, buf, buflen) < 0) ||
(wtls_crypto_HMAC_final (cobj, mac_secret,
cobj->mac_key_size, mac) < 0)) {
return -1;
}
return RET_OK;
}
/*
* Return the length of the key block to be generated as part
* of key generation.
*/
static UINT16
wtls_crypto_key_block_size (wtls_crypto_t *cobj)
{
return cobj->mac_key_size + cobj->key_material_length + cobj->iv_size;
}
/*
* Refresh the read keys for this connection state, using the given
* label and sequence number.
*/
INT16
wtls_crypto_key_refresh1 (void *connptr, SDL_Natural state)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_connection_state *cstate;
CHAR *label;
UINT16 seqnum;
UINT16 key_block_size;
BYTE p[34];
BYTE tmplabel[20];
if (state == CONSTATE_READ) {
cstate = &(conn->read);
label = "server";
}
else {
cstate = &(conn->write);
label = "client";
}
seqnum = cstate->last_refresh;
key_block_size = wtls_crypto_key_block_size (&(cstate->cobj));
/* Concatenate: seqnum + ServerHello.random + ClientHello.random */
p[0] = (seqnum >> 8) & 0xff;
p[1] = seqnum & 0xff;
B_COPYSTRINGN (p + 2, cstate->server_hello_random, 16);
B_COPYSTRINGN (p + 18, cstate->client_hello_random, 16);
sprintf (tmplabel, "%s expansion", label);
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
CRYPTa_PRF ((UINT16)conn->rec_proc,
cstate->cobj.hash_alg,
cstate->master_secret_id, NULL, 0,
tmplabel, p, 34, key_block_size);
return RET_OK;
}
INT16
wtls_crypto_key_refresh2 (void *connptr, SDL_Natural state,
void *buf, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_connection_state *cstate;
buflen = buflen;
if (state == CONSTATE_READ) {
cstate = &(conn->read);
}
else {
cstate = &(conn->write);
}
B_COPYSTRINGN (cstate->mac_secret, buf, cstate->cobj.mac_key_size);
B_COPYSTRINGN (cstate->encryption_key,
(BYTE *)buf + cstate->cobj.mac_key_size,
cstate->cobj.key_material_length);
B_COPYSTRINGN (cstate->iv, (BYTE *)buf + cstate->cobj.mac_key_size +
cstate->cobj.key_material_length, cstate->cobj.iv_size);
DEALLOC (&buf);
if (cstate->cobj.is_exportable) {
return RET_EXPORTABLE;
}
else {
return RET_OK;
}
}
INT16
wtls_crypto_key_refresh3 (void *connptr, SDL_Natural state)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_connection_state *cstate;
CHAR *label;
BYTE p[34];
BYTE tmplabel[20];
if (state == CONSTATE_READ) {
cstate = &(conn->read);
label = "server";
}
else {
cstate = &(conn->write);
label = "client";
}
/* Exportable algorithms have a shorter keyMaterialLength than keyLength,
* and hence need a further expansion to bring the key length up
* to the required length. */
B_COPYSTRINGN (p, cstate->client_hello_random, 16);
B_COPYSTRINGN (p + 16, cstate->server_hello_random, 16);
sprintf (tmplabel, "%s write key", label);
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
CRYPTa_PRF ((UINT16)conn->rec_proc,
cstate->cobj.hash_alg,
0, cstate->encryption_key,
cstate->cobj.key_material_length,
tmplabel, p, 32, cstate->cobj.key_size);
return RET_OK;
}
INT16
wtls_crypto_key_refresh4 (void *connptr, SDL_Natural state, void *buf,
SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_connection_state *cstate;
CHAR *label;
UINT16 seqnum;
BYTE p[34];
BYTE tmplabel[20];
buflen = buflen;
if (state == CONSTATE_READ) {
cstate = &(conn->read);
label = "server";
}
else {
cstate = &(conn->write);
label = "client";
}
seqnum = cstate->last_refresh;
B_COPYSTRINGN (cstate->encryption_key, buf, cstate->cobj.key_size);
DEALLOC (&buf);
p[0] = (seqnum >> 8) & 0xff;
p[1] = seqnum & 0xff;
B_COPYSTRINGN (p + 2, cstate->client_hello_random, 16);
B_COPYSTRINGN (p + 18, cstate->server_hello_random, 16);
sprintf (tmplabel, "%s write IV", label);
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
CRYPTa_PRF ((UINT16)conn->rec_proc,
cstate->cobj.hash_alg,
0, "", 0, tmplabel,
p, 34, cstate->cobj.iv_size);
return RET_OK;
}
INT16
wtls_crypto_key_refresh5 (void *connptr, SDL_Natural state,
void *buf, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_connection_state *cstate;
buflen = buflen;
if (state == CONSTATE_READ) {
cstate = &(conn->read);
}
else {
cstate = &(conn->write);
}
B_COPYSTRINGN (cstate->iv, buf, cstate->cobj.iv_size);
DEALLOC (&buf);
return RET_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -