Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


func_aes.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16 
17 /*! \file
18  *
19  * \brief AES encryption/decryption dialplan functions
20  *
21  * \author David Vossel <dvossel@digium.com>
22  * \ingroup functions
23  */
24 
25 /*** MODULEINFO
26  <use>crypto</use>
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 365398 $")
33 
34 #include "asterisk/module.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/app.h"
37 #include "asterisk/crypto.h"
38 
39 #define AES_BLOCK_SIZE 16
40 
41 /*** DOCUMENTATION
42  <function name="AES_ENCRYPT" language="en_US">
43  <synopsis>
44  Encrypt a string with AES given a 16 character key.
45  </synopsis>
46  <syntax>
47  <parameter name="key" required="true">
48  <para>AES Key</para>
49  </parameter>
50  <parameter name="string" required="true">
51  <para>Input string</para>
52  </parameter>
53  </syntax>
54  <description>
55  <para>Returns an AES encrypted string encoded in base64.</para>
56  </description>
57  <see-also>
58  <ref type="function">AES_DECRYPT</ref>
59  <ref type="function">BASE64_ENCODE</ref>
60  <ref type="function">BASE64_DECODE</ref>
61  </see-also>
62  </function>
63  <function name="AES_DECRYPT" language="en_US">
64  <synopsis>
65  Decrypt a string encoded in base64 with AES given a 16 character key.
66  </synopsis>
67  <syntax>
68  <parameter name="key" required="true">
69  <para>AES Key</para>
70  </parameter>
71  <parameter name="string" required="true">
72  <para>Input string.</para>
73  </parameter>
74  </syntax>
75  <description>
76  <para>Returns the plain text string.</para>
77  </description>
78  <see-also>
79  <ref type="function">AES_ENCRYPT</ref>
80  <ref type="function">BASE64_ENCODE</ref>
81  <ref type="function">BASE64_DECODE</ref>
82  </see-also>
83  </function>
84  ***/
85 
86 
87 static int aes_helper(struct ast_channel *chan, const char *cmd, char *data,
88  char *buf, size_t len)
89 {
90  unsigned char curblock[AES_BLOCK_SIZE] = { 0, };
91  char *tmp;
92  char *tmpP;
93  int data_len, encrypt;
94  ast_aes_encrypt_key ecx; /* AES 128 Encryption context */
96 
98  AST_APP_ARG(key);
99  AST_APP_ARG(data);
100  );
101 
103 
104  if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {
105  ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - missing argument!\n", cmd);
106  return -1;
107  }
108 
109  if (strlen(args.key) != AES_BLOCK_SIZE) { /* key must be of 16 characters in length, 128 bits */
110  ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - <key> parameter must be exactly 16 characters!\n", cmd);
111  return -1;
112  }
113 
114  ast_aes_set_encrypt_key((unsigned char *) args.key, &ecx); /* encryption: plaintext -> encryptedtext -> base64 */
115  ast_aes_set_decrypt_key((unsigned char *) args.key, &dcx); /* decryption: base64 -> encryptedtext -> plaintext */
116  tmp = ast_calloc(1, len); /* requires a tmp buffer for the base64 decode */
117  if (!tmp) {
118  ast_log(LOG_ERROR, "Unable to allocate memory for data\n");
119  return -1;
120  }
121  tmpP = tmp;
122  encrypt = strcmp("AES_DECRYPT", cmd); /* -1 if encrypting, 0 if decrypting */
123 
124  if (encrypt) { /* if decrypting first decode src to base64 */
125  ast_copy_string(tmp, args.data, len);
126  data_len = strlen(tmp);
127  } else {
128  data_len = ast_base64decode((unsigned char *) tmp, args.data, len);
129  }
130 
131  if (data_len >= len) { /* make sure to not go over buffer len */
132  ast_log(LOG_WARNING, "Syntax: %s(<keys>,<data>) - <data> exceeds buffer length. Result may be truncated!\n", cmd);
133  data_len = len - 1;
134  }
135 
136  while (data_len > 0) {
137  memset(curblock, 0, AES_BLOCK_SIZE);
138  memcpy(curblock, tmpP, (data_len < AES_BLOCK_SIZE) ? data_len : AES_BLOCK_SIZE);
139  if (encrypt) {
140  ast_aes_encrypt(curblock, (unsigned char *) tmpP, &ecx);
141  } else {
142  ast_aes_decrypt(curblock, (unsigned char *) tmpP, &dcx);
143  }
144  tmpP += AES_BLOCK_SIZE;
145  data_len -= AES_BLOCK_SIZE;
146  }
147 
148  if (encrypt) { /* if encrypting encode result to base64 */
149  ast_base64encode(buf, (unsigned char *) tmp, strlen(tmp), len);
150  } else {
151  memcpy(buf, tmp, len);
152  }
153  ast_free(tmp);
154 
155  return 0;
156 }
157 
159  .name = "AES_ENCRYPT",
160  .read = aes_helper,
161 };
162 
164  .name = "AES_DECRYPT",
165  .read = aes_helper,
166 };
167 
168 static int unload_module(void)
169 {
170  int res = ast_custom_function_unregister(&aes_decrypt_function);
171  return res | ast_custom_function_unregister(&aes_encrypt_function);
172 }
173 
174 static int load_module(void)
175 {
176  int res = ast_custom_function_register(&aes_decrypt_function);
177  res |= ast_custom_function_register(&aes_encrypt_function);
179 }
180 
181 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "AES dialplan functions",
182  .load = load_module,
183  .unload = unload_module,
184  .nonoptreq = "res_crypto",
185  );
Main Channel structure associated with a channel.
Definition: channel.h:742
Asterisk main include file. File version handling, generic pbx functions.
static int load_module(void)
Definition: func_aes.c:174
static int unload_module(void)
Definition: func_aes.c:168
int ast_aes_set_encrypt_key(const unsigned char *key, ast_aes_encrypt_key *ctx)
Set an encryption key.
Definition: res_crypto.c:461
#define LOG_WARNING
Definition: logger.h:144
Provide cryptographic signature routines.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
#define AES_BLOCK_SIZE
Definition: func_aes.c:39
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
void ast_aes_decrypt(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx)
AES decrypt data.
Definition: res_crypto.c:476
AES_KEY ast_aes_encrypt_key
Definition: crypto.h:35
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:279
void ast_aes_encrypt(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx)
AES encrypt data.
Definition: res_crypto.c:471
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
static struct ast_custom_function aes_decrypt_function
Definition: func_aes.c:163
static int aes_helper(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_aes.c:87
Core PBX routines and definitions.
#define LOG_ERROR
Definition: logger.h:155
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:357
static struct @350 args
int ast_aes_set_decrypt_key(const unsigned char *key, ast_aes_decrypt_key *ctx)
Set a decryption key.
Definition: res_crypto.c:466
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
AES_KEY ast_aes_decrypt_key
Definition: crypto.h:36
static struct ast_custom_function aes_encrypt_function
Definition: func_aes.c:158
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const char * name
Definition: pbx.h:96
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180