blob: 332d1bb46909ccd3f8c3c08ea078816f1ea4b158 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * Woodside Networks, Inc proprietary. All rights reserved.
24 * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmReplayCtr.c#2 $
25 *
26 * Contains definitions of various utilities for EAPoL frame
27 * parsing and creation.
28 *
29 * Author: Mayank D. Upadhyay
30 * Date: 19-June-2002
31 * History:-
32 * Date Modified by Modification Information
33 * ------------------------------------------------------
34 *
35 */
36#include "vos_types.h"
37#include "vos_trace.h"
38#include <bapRsnErrors.h>
39
40#include <bapRsnSsmReplayCtr.h>
41#include "vos_status.h"
42#include "vos_memory.h"
43#include "vos_utils.h"
44#include "vos_packet.h"
45
46//#include "aniSsmUtils.h"
47
48/*
49 * Opaque replay counter type. Does TX and RX side replay counter
50 * tracking. On the TX side, it returns monotonically increasing values
51 * of the counter and checks that the peer returned a value matching
52 * the one we sent. On the RX side, it makes sure that the peer sent a
53 * replay counter greater than the last one seen (excepting for the
54 * first time a check is made which the application has to special case.)
55 */
56struct sAniSsmReplayCtr {
57 v_U8_t size;
58 v_U8_t *buf;
59 v_U32_t currentValue;
60 v_U8_t init;
61};
62
63static int
64updateCtrBuf(tAniSsmReplayCtr *ctr);
65
66/**
67 * aniSsmReplayCtrCreate
68 *
69 * Creates a replay counter and initializes it for first time
70 * use. The initialization can be done randomly or with a passed in
71 * value like 0. In case this is going to be used on the RX side, it
72 * doesn't matter what the initialization is and can be optimized to
73 * a fixed value so as to avoid the overhead of obtaining a random
74 * value.
75 *
76 * @param ctrPtr a pointer that will be set to the newly allocated
77 * counter if the operation succeeds
78 * @param size the number of bytes that are desired in the counter
79 * @param initValue if this is negative and size is greater than 4,
80 * the initialization is done randomly. Otherwise, these bytes are
81 * copied into the least significant four or less octets of the
82 * counter, depending on the size of the counter. i.e., if the counter
83 * is only 2B, then the least significant 2B of initValue will be
84 * copied over.
85 *
86 * @return ANI_OK if the operation succeeds
87 */
88int
89aniSsmReplayCtrCreate(v_U32_t cryptHandle, tAniSsmReplayCtr **ctrPtr,
90 v_U8_t size,
91 int initValue)
92{
93 tAniSsmReplayCtr *ctr;
94
95 ctr = vos_mem_malloc( sizeof(tAniSsmReplayCtr) );
96 if( NULL == ctr )
97 {
98 return ANI_E_MALLOC_FAILED;
99 }
100
101 ctr->buf = vos_mem_malloc( size );
102 if (ctr->buf == NULL)
103 {
104 VOS_ASSERT( 0 );
105 vos_mem_free(ctr);
106 return ANI_E_MALLOC_FAILED;
107 }
108
109 ctr->size = size;
110
111 // We cannot randomly generate the most significant bytes if the
112 // total number of bytes is not greater than 4 (sizeof ANI_U32).
113 if (initValue < 0 && ctr->size <= 4)
114 initValue = 0;
115
116 // If initValue is negative, initialize the ctr randomly, else
117 // initialize it to what the user specified.
118 if (initValue < 0)
119 {
120 if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(cryptHandle, ctr->buf, ctr->size) ) )
121 {
122 return ANI_ERROR;
123 }
124 }
125 else {
126 ctr->currentValue = initValue - 1;
127 }
128
129 *ctrPtr = ctr;
130
131 return ANI_OK;
132}
133
134static int
135updateCtrBuf(tAniSsmReplayCtr *ctr)
136{
137
138 v_U32_t numBytes;
139 v_U32_t offset;
140 v_U32_t tmp;
141
142 tmp = vos_cpu_to_be32( ctr->currentValue );
143
144 numBytes = (4 <= ctr->size) ? 4 : ctr->size;
145 offset = 4 - numBytes;
146 vos_mem_copy(ctr->buf + ctr->size - numBytes,
147 ((v_U8_t *) &tmp) + offset, numBytes);
148
149 return ANI_OK;
150}
151
152/**
153 * aniSsmReplayCtrCmp
154 *
155 * Used to check if the passed in value is greater
156 * than, less than, or the same as the previous value.
157 *
158 * Can be used on the TX side to determine if the response to a
159 * request contains the same counter as the one in the request.
160 *
161 * Can be used on the RX side to determine if the request has a
162 * counter greater than the previous request, or if this is a
163 * retransmission of the previous request. The application should
164 * special-case the first time this is called on the RX side.
165 *
166 * @param ctr the current replay counter
167 * @param value the value to check against
168 *
169 * @return a negative value if current ctr is less than the
170 * given value, zero if they are the same, and a positive value if the
171 * current counter is greater than that of the given value.
172 */
173int
174aniSsmReplayCtrCmp(tAniSsmReplayCtr *ctr, v_U8_t *value)
175{
176 return vos_mem_compare2(ctr->buf, value, ctr->size);
177}
178
179/**
180 * aniSsmReplayCtrUpdate
181 *
182 * Used on the RX side to update the value of the current replay
183 * counter to that received in the next request. Typically this is
184 * called after it is determined that this is not a retransmission,
185 * and some sort of integrity checking is done on it.
186 *
187 * @param ctr the current replay counter
188 * @param value the value that it should be set to
189 *
190 * @return ANI_OK if the operation succeeds
191 */
192int
193aniSsmReplayCtrUpdate(tAniSsmReplayCtr *ctr,
194 v_U8_t *value)
195{
196 vos_mem_copy(ctr->buf, value, ctr->size);
197
198 return ANI_OK;
199}
200
201/**
202 * aniSsmReplayCtrNext
203 *
204 * Used on the RX side to obtain the next value that should be sent
205 * with a request. After this call, the current value is incremented
206 * by one.
207 *
208 * @param ctr the current replay counter
209 * @param value where the next counter value should be copied
210 * into. The caller must allocated enough storage for this.
211 *
212 * @return ANI_OK if the operation succeeds
213 */
214int
215aniSsmReplayCtrNext(tAniSsmReplayCtr *ctr,
216 v_U8_t *value)
217{
218 ctr->currentValue++;
219 updateCtrBuf(ctr);
220 vos_mem_copy(value, ctr->buf, ctr->size);
221
222 return ANI_OK;
223}
224
225/**
226 * aniSsmReplayCtrFree
227 *
228 * Frees the replay counter context.
229 *
230 * @param ctr the replay counter to free.
231 *
232 * @return ANI_OK if the operation succeeds
233 */
234int
235aniSsmReplayCtrFree(tAniSsmReplayCtr *ctr)
236{
237
238 if (ctr->buf != NULL)
239 vos_mem_free(ctr->buf);
240
241 vos_mem_free(ctr);
242
243 return ANI_OK;
244}