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