1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include "../rt_config.h"
39
40UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
41UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
42UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
43UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
44UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
45UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
46UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
47UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
48
49UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
50UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
51UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
52UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
53UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
54UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
55
56UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05};
57UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06};
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86VOID PRF(
87 IN UCHAR *key,
88 IN INT key_len,
89 IN UCHAR *prefix,
90 IN INT prefix_len,
91 IN UCHAR *data,
92 IN INT data_len,
93 OUT UCHAR *output,
94 IN INT len)
95{
96 INT i;
97 UCHAR *input;
98 INT currentindex = 0;
99 INT total_len;
100
101
102 os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
103
104 if (input == NULL)
105 {
106 DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
107 return;
108 }
109
110
111 NdisMoveMemory(input, prefix, prefix_len);
112
113
114 input[prefix_len] = 0;
115
116
117 NdisMoveMemory(&input[prefix_len + 1], data, data_len);
118 total_len = prefix_len + 1 + data_len;
119
120
121
122 input[total_len] = 0;
123 total_len++;
124
125
126
127 for (i = 0; i < (len + 19) / 20; i++)
128 {
129 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
130 currentindex += 20;
131
132
133 input[total_len - 1]++;
134 }
135 os_free_mem(NULL, input);
136}
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162VOID WpaCountPTK(
163 IN PRTMP_ADAPTER pAd,
164 IN UCHAR *PMK,
165 IN UCHAR *ANonce,
166 IN UCHAR *AA,
167 IN UCHAR *SNonce,
168 IN UCHAR *SA,
169 OUT UCHAR *output,
170 IN UINT len)
171{
172 UCHAR concatenation[76];
173 UINT CurrPos = 0;
174 UCHAR temp[32];
175 UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
176 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
177
178
179 NdisZeroMemory(temp, sizeof(temp));
180 NdisZeroMemory(concatenation, 76);
181
182
183 if (RTMPCompareMemory(SA, AA, 6) == 1)
184 NdisMoveMemory(concatenation, AA, 6);
185 else
186 NdisMoveMemory(concatenation, SA, 6);
187 CurrPos += 6;
188
189
190 if (RTMPCompareMemory(SA, AA, 6) == 1)
191 NdisMoveMemory(&concatenation[CurrPos], SA, 6);
192 else
193 NdisMoveMemory(&concatenation[CurrPos], AA, 6);
194
195
196
197 NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
198 CurrPos += 6;
199
200
201 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
202 NdisMoveMemory(&concatenation[CurrPos], temp, 32);
203 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
204 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
205 else
206 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
207 CurrPos += 32;
208
209
210 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
211 NdisMoveMemory(&concatenation[CurrPos], temp, 32);
212 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
213 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
214 else
215 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
216 CurrPos += 32;
217
218 hex_dump("concatenation=", concatenation, 76);
219
220
221 PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
222
223}
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242VOID GenRandom(
243 IN PRTMP_ADAPTER pAd,
244 IN UCHAR *macAddr,
245 OUT UCHAR *random)
246{
247 INT i, curr;
248 UCHAR local[80], KeyCounter[32];
249 UCHAR result[80];
250 ULONG CurrentTime;
251 UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
252
253
254 NdisZeroMemory(result, 80);
255 NdisZeroMemory(local, 80);
256 NdisZeroMemory(KeyCounter, 32);
257
258 for (i = 0; i < 32; i++)
259 {
260
261 COPY_MAC_ADDR(local, macAddr);
262 curr = MAC_ADDR_LEN;
263
264
265 NdisGetSystemUpTime(&CurrentTime);
266 NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
267 curr += sizeof(CurrentTime);
268
269
270 NdisMoveMemory(&local[curr], result, 32);
271 curr += 32;
272
273
274 NdisMoveMemory(&local[curr], &i, 2);
275 curr += 2;
276
277
278 PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
279 }
280
281 NdisMoveMemory(random, result, 32);
282}
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304static VOID RTMPInsertRsnIeCipher(
305 IN PRTMP_ADAPTER pAd,
306 IN UCHAR ElementID,
307 IN UINT WepStatus,
308 IN BOOLEAN bMixCipher,
309 IN UCHAR FlexibleCipher,
310 OUT PUCHAR pRsnIe,
311 OUT UCHAR *rsn_len)
312{
313 UCHAR PairwiseCnt;
314
315 *rsn_len = 0;
316
317
318 if (ElementID == Wpa2Ie)
319 {
320 RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
321
322
323 pRsnie_cipher->version = 1;
324
325 switch (WepStatus)
326 {
327
328 case Ndis802_11Encryption2Enabled:
329 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
330 pRsnie_cipher->ucount = 1;
331 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
332 *rsn_len = sizeof(RSNIE2);
333 break;
334
335
336 case Ndis802_11Encryption3Enabled:
337 if (bMixCipher)
338 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
339 else
340 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
341 pRsnie_cipher->ucount = 1;
342 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
343 *rsn_len = sizeof(RSNIE2);
344 break;
345
346
347 case Ndis802_11Encryption4Enabled:
348 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
349
350 PairwiseCnt = 1;
351
352 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
353 {
354 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
355
356 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
357 {
358 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
359 PairwiseCnt = 2;
360 }
361 }
362 else
363 {
364
365 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
366 }
367
368 pRsnie_cipher->ucount = PairwiseCnt;
369 *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
370 break;
371 }
372
373 if ((pAd->OpMode == OPMODE_STA) &&
374 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
375 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
376 {
377 UINT GroupCipher = pAd->StaCfg.GroupCipher;
378 switch(GroupCipher)
379 {
380 case Ndis802_11GroupWEP40Enabled:
381 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
382 break;
383 case Ndis802_11GroupWEP104Enabled:
384 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
385 break;
386 }
387 }
388
389
390 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
391 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
392 }
393 else
394 {
395 RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
396
397
398 NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
399 pRsnie_cipher->version = 1;
400
401 switch (WepStatus)
402 {
403
404 case Ndis802_11Encryption2Enabled:
405 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
406 pRsnie_cipher->ucount = 1;
407 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
408 *rsn_len = sizeof(RSNIE);
409 break;
410
411
412 case Ndis802_11Encryption3Enabled:
413 if (bMixCipher)
414 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
415 else
416 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
417 pRsnie_cipher->ucount = 1;
418 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
419 *rsn_len = sizeof(RSNIE);
420 break;
421
422
423 case Ndis802_11Encryption4Enabled:
424 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
425
426 PairwiseCnt = 1;
427
428 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
429 {
430 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
431
432 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
433 {
434 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
435 PairwiseCnt = 2;
436 }
437 }
438 else
439 {
440
441 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
442 }
443
444 pRsnie_cipher->ucount = PairwiseCnt;
445 *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
446 break;
447 }
448
449 if ((pAd->OpMode == OPMODE_STA) &&
450 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
451 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
452 {
453 UINT GroupCipher = pAd->StaCfg.GroupCipher;
454 switch(GroupCipher)
455 {
456 case Ndis802_11GroupWEP40Enabled:
457 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
458 break;
459 case Ndis802_11GroupWEP104Enabled:
460 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
461 break;
462 }
463 }
464
465
466 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
467 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
468 }
469}
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490static VOID RTMPInsertRsnIeAKM(
491 IN PRTMP_ADAPTER pAd,
492 IN UCHAR ElementID,
493 IN UINT AuthMode,
494 IN UCHAR apidx,
495 OUT PUCHAR pRsnIe,
496 OUT UCHAR *rsn_len)
497{
498 RSNIE_AUTH *pRsnie_auth;
499
500 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
501
502
503 if (ElementID == Wpa2Ie)
504 {
505 switch (AuthMode)
506 {
507 case Ndis802_11AuthModeWPA2:
508 case Ndis802_11AuthModeWPA1WPA2:
509 pRsnie_auth->acount = 1;
510 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
511 break;
512
513 case Ndis802_11AuthModeWPA2PSK:
514 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
515 pRsnie_auth->acount = 1;
516 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
517 break;
518 }
519 }
520 else
521 {
522 switch (AuthMode)
523 {
524 case Ndis802_11AuthModeWPA:
525 case Ndis802_11AuthModeWPA1WPA2:
526 pRsnie_auth->acount = 1;
527 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
528 break;
529
530 case Ndis802_11AuthModeWPAPSK:
531 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
532 pRsnie_auth->acount = 1;
533 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
534 break;
535
536 case Ndis802_11AuthModeWPANone:
537 pRsnie_auth->acount = 1;
538 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
539 break;
540 }
541 }
542
543 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
544
545 (*rsn_len) += sizeof(RSNIE_AUTH);
546
547}
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567static VOID RTMPInsertRsnIeCap(
568 IN PRTMP_ADAPTER pAd,
569 IN UCHAR ElementID,
570 IN UCHAR apidx,
571 OUT PUCHAR pRsnIe,
572 OUT UCHAR *rsn_len)
573{
574 RSN_CAPABILITIES *pRSN_Cap;
575
576
577 if (ElementID == WpaIe)
578 return;
579
580 pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
581
582
583 pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
584
585 (*rsn_len) += sizeof(RSN_CAPABILITIES);
586
587}
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608VOID RTMPMakeRSNIE(
609 IN PRTMP_ADAPTER pAd,
610 IN UINT AuthMode,
611 IN UINT WepStatus,
612 IN UCHAR apidx)
613{
614 PUCHAR pRsnIe = NULL;
615 UCHAR *rsnielen_cur_p = 0;
616 UCHAR *rsnielen_ex_cur_p = 0;
617 UCHAR PrimaryRsnie;
618 BOOLEAN bMixCipher = FALSE;
619 UCHAR p_offset;
620 WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;
621
622 rsnielen_cur_p = NULL;
623 rsnielen_ex_cur_p = NULL;
624
625 {
626 {
627 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
628 {
629 if (AuthMode < Ndis802_11AuthModeWPA)
630 return;
631 }
632 else
633 {
634
635
636 if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
637 (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
638 (AuthMode != Ndis802_11AuthModeWPANone)
639 )
640 return;
641 }
642
643 DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
644
645
646 pAd->StaCfg.RSNIE_Len = 0;
647 NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
648
649
650 rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
651 pRsnIe = pAd->StaCfg.RSN_IE;
652
653 bMixCipher = pAd->StaCfg.bMixCipher;
654 }
655 }
656
657
658 if ((AuthMode == Ndis802_11AuthModeWPA) ||
659 (AuthMode == Ndis802_11AuthModeWPAPSK) ||
660 (AuthMode == Ndis802_11AuthModeWPANone) ||
661 (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
662 (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
663 PrimaryRsnie = WpaIe;
664 else
665 PrimaryRsnie = Wpa2Ie;
666
667 {
668
669
670 RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
671
672
673 RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
674
675
676 RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
677 }
678
679
680 *rsnielen_cur_p = p_offset;
681
682 hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
683
684
685}
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704BOOLEAN RTMPCheckWPAframe(
705 IN PRTMP_ADAPTER pAd,
706 IN PMAC_TABLE_ENTRY pEntry,
707 IN PUCHAR pData,
708 IN ULONG DataByteCount,
709 IN UCHAR FromWhichBSSID)
710{
711 ULONG Body_len;
712 BOOLEAN Cancelled;
713
714
715 if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
716 return FALSE;
717
718
719
720 if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
721
722 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
723 {
724 pData += 6;
725 }
726
727 if (NdisEqualMemory(EAPOL, pData, 2))
728 {
729 pData += 2;
730 }
731 else
732 return FALSE;
733
734 switch (*(pData+1))
735 {
736 case EAPPacket:
737 Body_len = (*(pData+2)<<8) | (*(pData+3));
738 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
739 break;
740 case EAPOLStart:
741 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
742 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
743 {
744 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
745 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
746 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
747 }
748 break;
749 case EAPOLLogoff:
750 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
751 break;
752 case EAPOLKey:
753 Body_len = (*(pData+2)<<8) | (*(pData+3));
754 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
755 break;
756 case EAPOLASFAlert:
757 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
758 break;
759 default:
760 return FALSE;
761
762 }
763 return TRUE;
764}
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781VOID AES_GTK_KEY_UNWRAP(
782 IN UCHAR *key,
783 OUT UCHAR *plaintext,
784 IN UCHAR c_len,
785 IN UCHAR *ciphertext)
786
787{
788 UCHAR A[8], BIN[16], BOUT[16];
789 UCHAR xor;
790 INT i, j;
791 aes_context aesctx;
792 UCHAR *R;
793 INT num_blocks = c_len/8;
794
795
796 os_alloc_mem(NULL, (PUCHAR *)&R, 512);
797
798 if (R == NULL)
799 {
800 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
801 return;
802 }
803
804
805 NdisMoveMemory(A, ciphertext, 8);
806
807 for(i = 0; i < (c_len-8); i++)
808 {
809 R[ i] = ciphertext[i + 8];
810 }
811
812 rtmp_aes_set_key(&aesctx, key, 128);
813
814 for(j = 5; j >= 0; j--)
815 {
816 for(i = (num_blocks-1); i > 0; i--)
817 {
818 xor = (num_blocks -1 )* j + i;
819 NdisMoveMemory(BIN, A, 8);
820 BIN[7] = A[7] ^ xor;
821 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
822 rtmp_aes_decrypt(&aesctx, BIN, BOUT);
823 NdisMoveMemory(A, &BOUT[0], 8);
824 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
825 }
826 }
827
828
829 for(i = 0; i < c_len; i++)
830 {
831 plaintext[i] = R[i];
832 }
833
834
835 os_free_mem(NULL, R);
836}
837