📄 ust.c
字号:
/* * ust.c * * C implementation of the universal security transform * * David A. McGrew * Cisco Systems, Inc. *//* * * Copyright (c) 2001, 2002, Cisco Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */#include "ust.h"#define PRINT_DEBUG 0err_status_tust_init(ust_ctx_t *ctx, /* ust context */ int index_length, /* number of octets in the index */ cipher_type_t *cipher_algo, /* keystream generator type */ octet_t *cipher_key, /* cipher key */ int cipher_key_len, /* number of octets in cipher key */ auth_type_t *auth_algo, /* auth algorithm specification */ octet_t *auth_key, /* auth key */ int auth_key_len, /* number of octets in the auth key */ int auth_tag_len, /* number of octets in the auth tag */ int replay_window_len /* bits in replay window (0 == none) */ ) { err_status_t stat; /* check index_length to see if we can support the value requested */ if (index_length != 6) return err_status_bad_param; /* check replay_window_len to see if we can support the value requested */ if (replay_window_len != 128) return err_status_bad_param; /* allocate then initialize cipher */ stat = cipher_type_alloc(cipher_algo, &ctx->c, cipher_key_len); if (stat) return err_status_alloc_fail; cipher_init(ctx->c, cipher_key, cipher_key); /* DAM - SALT! */ if (stat) { cipher_dealloc(ctx->c); return err_status_init_fail; } /* allocate then initialize auth function */ stat = auth_type_alloc(auth_algo, &ctx->h, auth_key_len, auth_tag_len); if (stat) { cipher_dealloc(ctx->c); return err_status_alloc_fail; } stat = auth_init(ctx->h, auth_key, auth_key_len); if (stat) { cipher_dealloc(ctx->c); auth_dealloc(ctx->h); return err_status_init_fail; } /* allocate storage for the authentication tag */ ctx->auth_tag = (octet_t *)malloc(auth_tag_len); if (ctx->auth_tag == NULL) { cipher_dealloc(ctx->c); auth_dealloc(ctx->h); return err_status_alloc_fail; } return err_status_ok;}/* * ust_tag_len(ctx) returns the length (in octets) of the * authentication tag for the ust context ctx. * * this function can be used to determine the storage * space required to hold a particular tag, if need be */inline unsigned int ust_tag_len(ust_ctx_t *ctx) { return ctx->h->out_len;}/* * the ust_xfm function * * ctx is the ust context, which holds the cipher and hash function * keys and parameters, as well as anti-replay information * * idx is the packet index, a 48-bit unsigned integer which * should be unique for each invocation of ust_xfm for a * given ctx * * if auth_start != NULL, then authentication is provided to the * auth_len octets of data at auth_start by computing the * authentication tag and writing it to *tag; otherwise, the * authentication tag is not computed * * if enc_start != NULL, then encryption is provided to the * enc_len octets of data at enc_start by exoring keystream * into that data; otherwise, no encryption is done * * tag points to the authentication tag; after ust_xfm returns, * it contains the tag corresonding to the data at auth_start * (if auth_start != NULL) -- note that there MUST be at least * ust_tag_len(ctx) octets of storage at *tag! */err_status_tust_xfm(ust_ctx_t *ctx, /* ust context */ xtd_seq_num_t idx, /* index */ octet_t *enc_start, /* pointer to encryption start */ int enc_len, /* number of octets to encrypt */ octet_t *auth_start, /* pointer to authentication start */ int auth_len, /* number of octets to authenticate */ octet_t *tag /* authentication tag */ ) { int stat; /* set the index to idx */ stat = cipher_set_segment(ctx->c, idx); if (stat) return err_status_cipher_fail; /* if auth_start is non-null, then put keystream into tag */ if (auth_start) { /* zeroize tag, then add in keystream */ octet_string_set_to_zero(tag, ctx->h->out_len); stat = cipher_encrypt(ctx->c, tag, ctx->h->out_len);#if PRINT_DEBUG printf("ust_xfm prefix: %s\n", octet_string_hex_string(tag, 8));#endif if (stat) return err_status_cipher_fail; } /* if enc_start is non-null, encrypt data */ if (enc_start) { stat = cipher_encrypt(ctx->c, enc_start, enc_len); if (stat) return err_status_cipher_fail; } /* if auth_start is non-null, authenticate message */ if (auth_start) { stat = auth_compute(ctx->h, auth_start, auth_len, tag);#if PRINT_DEBUG printf("ust_xfm tag: %s\n", octet_string_hex_string(tag, 8));#endif if (stat) return err_status_auth_fail; } return err_status_ok;}/* * the ust_inv_xfm function (ust inverse transform) * * ctx is the ust context, which holds the cipher and hash function * keys and parameters, as well as anti-replay information * * idx is the packet index, a 48-bit unsigned integer which * should be unique for each invocation of ust_xfm for a * given ctx * * if auth_start != NULL, then authentication is expected on the * auth_len octets of data at auth_start by computing the * authentication tag and comparing it to the value at *tag; * otherwise, no authentication check is performed * * if enc_start != NULL, then decryption is done to the enc_len * octets of data at enc_start by exoring keystream into that data; * otherwise, no decryption is done * * tag points to the authentication tag; if auth_start != NULL, * then *tag is expected to hold the authentication tag corresponding * to the data at *auth_start -- note that there MUST be at least * ust_tag_len(ctx) octets of readable data at *tag! */err_status_tust_inv_xfm(ust_ctx_t *ctx, /* ust context */ xtd_seq_num_t idx, /* index */ octet_t *enc_start, /* pointer to encryption start */ int enc_len, /* number of octets to encrypt */ octet_t *auth_start, /* pointer to authentication start */ int auth_len, /* number of octets to authenticate */ octet_t *tag /* authentication tag */ ) { int stat; /* set the index to idx */ stat = cipher_set_segment(ctx->c, idx); if (stat) return err_status_cipher_fail; /* * if auth_start is non-null, then put keystream into tag in ctx, * compute auth_tag and compare to tag */ if (auth_start) { /* zeroize tag, then add in keystream */ octet_string_set_to_zero(ctx->auth_tag, ctx->h->out_len); stat = cipher_encrypt(ctx->c, ctx->auth_tag, ctx->h->out_len);#if PRINT_DEBUG printf("ust_inv_xfm prefix: %s\n", octet_string_hex_string(ctx->auth_tag, 8));#endif if (stat) return err_status_cipher_fail; /* compute hash then compare to tag value */ stat = auth_compute(ctx->h, auth_start, auth_len, ctx->auth_tag); if (stat) return err_status_auth_fail;#if PRINT_DEBUG printf("ust_inv_xfm tag: %s\n", octet_string_hex_string(ctx->auth_tag, 8)); printf("tag (from arglist): %s\n", octet_string_hex_string(tag, 8));#endif if (octet_string_is_eq(ctx->auth_tag, tag, ctx->h->out_len)) { return err_status_auth_fail; } } /* if enc_start is non-null, decrypt data */ if (enc_start) { stat = cipher_encrypt(ctx->c, enc_start, enc_len); if (stat) return err_status_cipher_fail; } return err_status_ok;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -