FreeRDP
Loading...
Searching...
No Matches
rc4.c
1
20#include <winpr/assert.h>
21#include <winpr/cast.h>
22
23#include "rc4.h"
24
25#define CTX_SIZE 256
26
27struct winpr_int_rc4_ctx
28{
29 size_t i;
30 size_t j;
31 BYTE s[CTX_SIZE];
32 BYTE t[CTX_SIZE];
33};
34
35static void swap(BYTE* p1, BYTE* p2)
36{
37 BYTE t = *p1;
38 *p1 = *p2;
39 *p2 = t;
40}
41
42winpr_int_RC4_CTX* winpr_int_rc4_new(const BYTE* key, size_t keylength)
43{
44 winpr_int_RC4_CTX* ctx = calloc(1, sizeof(winpr_int_RC4_CTX));
45 if (!ctx)
46 return NULL;
47
48 for (size_t i = 0; i < CTX_SIZE; i++)
49 {
50 ctx->s[i] = WINPR_ASSERTING_INT_CAST(BYTE, i);
51 ctx->t[i] = key[i % keylength];
52 }
53
54 size_t j = 0;
55 for (size_t i = 0; i < CTX_SIZE; i++)
56 {
57 j = (j + ctx->s[i] + ctx->t[i]) % CTX_SIZE;
58 swap(&ctx->s[i], &ctx->s[j]);
59 }
60 return ctx;
61}
62
63void winpr_int_rc4_free(winpr_int_RC4_CTX* ctx)
64{
65 free(ctx);
66}
67
68BOOL winpr_int_rc4_update(winpr_int_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
69{
70 WINPR_ASSERT(ctx);
71
72 size_t t1 = ctx->i;
73 size_t t2 = ctx->j;
74 for (size_t i = 0; i < length; i++)
75 {
76 t1 = (t1 + 1) % CTX_SIZE;
77 t2 = (t2 + ctx->s[t1]) % CTX_SIZE;
78 swap(&ctx->s[t1], &ctx->s[t2]);
79
80 const size_t idx = ((size_t)ctx->s[t1] + ctx->s[t2]) % CTX_SIZE;
81 const BYTE val = ctx->s[idx];
82 const BYTE out = *input++ ^ val;
83 *output++ = out;
84 }
85
86 ctx->i = t1;
87 ctx->j = t2;
88 return TRUE;
89}