2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2011-2014 Paul Kocialkowski <contact@paulk.fr>
6 * libsamsung-ipc is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * libsamsung-ipc is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
29 #include <openssl/md5.h>
31 #include <samsung-ipc.h>
36 char *ipc_nv_data_md5_calculate(const char *path, const char *secret,
37 size_t size, size_t chunk_size)
40 char *md5_string = NULL;
41 unsigned char md5_hash[MD5_DIGEST_LENGTH] = { 0 };
48 data = file_data_read(path, size, chunk_size, 0);
53 MD5_Update(&ctx, data, size);
54 MD5_Update(&ctx, secret, strlen(secret));
55 MD5_Final((unsigned char *) &md5_hash, &ctx);
57 md5_string = data2string(&md5_hash, sizeof(md5_hash));
62 int ipc_nv_data_path_check(struct ipc_client *client)
72 path = ipc_client_nv_data_path(client);
73 size = ipc_client_nv_data_size(client);
74 if (path == NULL || size == 0)
79 ipc_client_log(client, "Checking nv_data path failed");
83 if (st.st_size != size) {
84 ipc_client_log(client, "Checking nv_data size failed");
88 ipc_client_log(client, "Checked nv_data path");
93 int ipc_nv_data_md5_path_check(struct ipc_client *client)
102 md5_path = ipc_client_nv_data_md5_path(client);
103 if (md5_path == NULL)
106 rc = stat(md5_path, &st);
108 ipc_client_log(client, "Checking nv_data md5 path failed");
112 if (st.st_size < 2 * sizeof(char) * MD5_DIGEST_LENGTH) {
113 ipc_client_log(client, "Checking nv_data md5 size failed");
117 ipc_client_log(client, "Checked nv_data md5 path");
122 int ipc_nv_data_backup_path_check(struct ipc_client *client)
132 backup_path = ipc_client_nv_data_backup_path(client);
133 size = ipc_client_nv_data_size(client);
134 if (backup_path == NULL || size == 0)
137 rc = stat(backup_path, &st);
139 ipc_client_log(client, "Checking nv_data backup path failed");
143 if (st.st_size != size) {
144 ipc_client_log(client, "Checking nv_data backup size failed");
148 ipc_client_log(client, "Checked nv_data backup path");
153 int ipc_nv_data_backup_md5_path_check(struct ipc_client *client)
156 char *backup_md5_path;
162 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
163 if (backup_md5_path == NULL)
166 rc = stat(backup_md5_path, &st);
168 ipc_client_log(client, "Checking nv_data backup md5 path failed");
172 if (st.st_size < 2 * sizeof(char) * MD5_DIGEST_LENGTH) {
173 ipc_client_log(client, "Checking nv_data backup md5 size failed");
177 ipc_client_log(client, "Checked nv_data backup md5 path");
182 int ipc_nv_data_check(struct ipc_client *client)
189 char *md5_string = NULL;
198 path = ipc_client_nv_data_path(client);
199 md5_path = ipc_client_nv_data_md5_path(client);
200 secret = ipc_client_nv_data_secret(client);
201 size = ipc_client_nv_data_size(client);
202 chunk_size = ipc_client_nv_data_chunk_size(client);
203 if (path == NULL || md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
206 rc = ipc_nv_data_path_check(client);
208 ipc_client_log(client, "Checking nv_data path failed");
212 rc = ipc_nv_data_md5_path_check(client);
214 ipc_client_log(client, "Checking nv_data md5 path failed");
218 md5_string = ipc_nv_data_md5_calculate(path, secret, size, chunk_size);
219 if (md5_string == NULL) {
220 ipc_client_log(client, "Calculating nv_data md5 failed");
223 ipc_client_log(client, "Calculated nv_data md5: %s", md5_string);
225 length = strlen(md5_string);
227 buffer = file_data_read(md5_path, length, length, 0);
228 if (buffer == NULL) {
229 ipc_client_log(client, "Reading nv_data md5 failed");
233 string = strndup(buffer, length);
234 ipc_client_log(client, "Read nv_data md5: %s", string);
236 rc = strncmp(md5_string, string, length);
238 ipc_client_log(client, "Matching nv_data md5 failed");
255 if (md5_string != NULL)
261 int ipc_nv_data_backup_check(struct ipc_client *client)
264 char *backup_md5_path;
268 char *backup_md5_string = NULL;
277 backup_path = ipc_client_nv_data_backup_path(client);
278 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
279 secret = ipc_client_nv_data_secret(client);
280 size = ipc_client_nv_data_size(client);
281 chunk_size = ipc_client_nv_data_chunk_size(client);
282 if (backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
285 rc = ipc_nv_data_backup_path_check(client);
287 ipc_client_log(client, "Checking nv_data backup path failed");
291 rc = ipc_nv_data_backup_md5_path_check(client);
293 ipc_client_log(client, "Checking nv_data backup md5 path failed");
297 backup_md5_string = ipc_nv_data_md5_calculate(backup_path, secret, size, chunk_size);
298 if (backup_md5_string == NULL) {
299 ipc_client_log(client, "Calculating nv_data backup md5 failed");
302 ipc_client_log(client, "Calculated nv_data backup md5: %s", backup_md5_string);
304 length = strlen(backup_md5_string);
306 buffer = file_data_read(backup_md5_path, length, length, 0);
307 if (buffer == NULL) {
308 ipc_client_log(client, "Reading nv_data backup md5 failed");
312 string = strndup(buffer, length);
313 ipc_client_log(client, "Read nv_data backup md5: %s", string);
315 rc = strncmp(backup_md5_string, string, length);
317 ipc_client_log(client, "Matching nv_data backup md5 failed");
334 if (backup_md5_string != NULL)
335 free(backup_md5_string);
340 int ipc_nv_data_backup(struct ipc_client *client)
345 char *backup_md5_path;
349 char *md5_string = NULL;
356 path = ipc_client_nv_data_path(client);
357 backup_path = ipc_client_nv_data_backup_path(client);
358 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
359 secret = ipc_client_nv_data_secret(client);
360 size = ipc_client_nv_data_size(client);
361 chunk_size = ipc_client_nv_data_chunk_size(client);
362 if (path == NULL || backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
365 rc = ipc_nv_data_path_check(client);
367 ipc_client_log(client, "Checking nv_data path failed");
371 data = file_data_read(path, size, chunk_size, 0);
373 ipc_client_log(client, "Reading nv_data failed");
377 md5_string = ipc_nv_data_md5_calculate(path, secret, size, chunk_size);
378 if (md5_string == NULL) {
379 ipc_client_log(client, "Calculating nv_data md5 failed");
383 length = strlen(md5_string);
385 rc = unlink(backup_path);
387 ipc_client_log(client, "Removing nv_data backup path failed");
389 rc = file_data_write(backup_path, data, size, chunk_size, 0);
391 ipc_client_log(client, "Writing nv_data backup failed");
395 rc = unlink(backup_md5_path);
397 ipc_client_log(client, "Removing nv_data backup md5 path failed");
399 rc = file_data_write(backup_md5_path, md5_string, length, length, 0);
401 ipc_client_log(client, "Writing nv_data backup md5 failed");
405 ipc_client_log(client, "Backed up nv_data");
414 if (md5_string != NULL)
423 int ipc_nv_data_restore(struct ipc_client *client)
429 char *backup_md5_path;
439 path = ipc_client_nv_data_path(client);
440 md5_path = ipc_client_nv_data_md5_path(client);
441 backup_path = ipc_client_nv_data_backup_path(client);
442 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
443 secret = ipc_client_nv_data_secret(client);
444 size = ipc_client_nv_data_size(client);
445 chunk_size = ipc_client_nv_data_chunk_size(client);
446 if (path == NULL || md5_path == NULL || backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
449 rc = ipc_nv_data_backup_check(client);
451 ipc_client_log(client, "Checking nv_data backup failed");
455 data = file_data_read(backup_path, size, chunk_size, 0);
457 ipc_client_log(client, "Reading nv_data backup failed");
463 ipc_client_log(client, "Removing nv_data path failed");
465 rc = file_data_write(path, data, size, chunk_size, 0);
467 ipc_client_log(client, "Writing nv_data failed");
474 length = 2 * sizeof(char) * MD5_DIGEST_LENGTH;
476 data = file_data_read(backup_md5_path, length, length, 0);
478 ipc_client_log(client, "Reading nv_data backup md5 failed");
482 rc = unlink(md5_path);
484 ipc_client_log(client, "Removing nv_data md5 path failed");
486 rc = file_data_write(md5_path, data, length, length, 0);
488 ipc_client_log(client, "Writing nv_data md5 failed");
492 ipc_client_log(client, "Restored nv_data");
507 void *ipc_nv_data_load(struct ipc_client *client)
518 path = ipc_client_nv_data_path(client);
519 size = ipc_client_nv_data_size(client);
520 chunk_size = ipc_client_nv_data_chunk_size(client);
521 if (path == NULL || size == 0 || chunk_size == 0)
524 rc = ipc_nv_data_check(client);
526 ipc_client_log(client, "Checking nv_data failed");
528 rc = ipc_nv_data_restore(client);
530 ipc_client_log(client, "Restoring nv_data failed");
534 rc = ipc_nv_data_check(client);
536 ipc_client_log(client, "Checking nv_data failed");
541 rc = ipc_nv_data_backup_path_check(client);
543 ipc_client_log(client, "Checking nv_data backup path failed");
545 rc = ipc_nv_data_backup(client);
547 ipc_client_log(client, "Backing up nv_data failed");
550 data = file_data_read(path, size, chunk_size, 0);
552 ipc_client_log(client, "Reading nv_data failed");
559 void *ipc_nv_data_read(struct ipc_client *client, size_t size, size_t offset)
569 path = ipc_client_nv_data_path(client);
570 chunk_size = ipc_client_nv_data_chunk_size(client);
571 if (path == NULL || chunk_size == 0)
574 rc = ipc_nv_data_path_check(client);
576 ipc_client_log(client, "Checking nv_data path failed");
580 data = file_data_read(path, size, chunk_size, offset);
582 ipc_client_log(client, "Reading nv_data failed");
589 int ipc_nv_data_write(struct ipc_client *client, const void *data, size_t size,
596 char *md5_string = NULL;
603 path = ipc_client_nv_data_path(client);
604 md5_path = ipc_client_nv_data_md5_path(client);
605 secret = ipc_client_nv_data_secret(client);
606 chunk_size = ipc_client_nv_data_chunk_size(client);
607 if (path == NULL || md5_path == NULL || secret == NULL || chunk_size == 0)
610 rc = ipc_nv_data_path_check(client);
612 ipc_client_log(client, "Checking nv_data path failed");
616 rc = file_data_write(path, data, size, chunk_size, offset);
618 ipc_client_log(client, "Writing nv_data failed");
622 size = ipc_client_nv_data_size(client);
626 md5_string = ipc_nv_data_md5_calculate(path, secret, size, chunk_size);
627 if (md5_string == NULL) {
628 ipc_client_log(client, "Calculating nv_data md5 failed");
632 length = strlen(md5_string);
634 rc = unlink(md5_path);
636 ipc_client_log(client, "Removing nv_data md5 path failed");
640 rc = file_data_write(md5_path, md5_string, length, length, 0);
642 ipc_client_log(client, "Writing nv_data md5 failed");
653 if (md5_string != NULL)
659 void *ipc_rfs_nv_read_item_response_setup(const void *data, size_t size,
662 struct ipc_rfs_nv_read_item_response_header *header;
665 unsigned char confirm;
668 if (data != NULL && size > 0) {
669 length = sizeof(struct ipc_rfs_nv_read_item_response_header) + size;
672 length = sizeof(struct ipc_rfs_nv_read_item_response_header);
678 buffer = calloc(1, length);
680 header = (struct ipc_rfs_nv_read_item_response_header *) buffer;
681 header->confirm = confirm;
682 header->offset = (unsigned int) offset;
683 header->length = (unsigned int) size;
685 if (data != NULL && size > 0) {
686 p = (unsigned char *) buffer;
687 p += sizeof(struct ipc_rfs_nv_read_item_response_header);
689 memcpy(p, data, size);
695 // vim:ts=4:sw=4:expandtab