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>
35 char *ipc_nv_data_md5_calculate(const char *path, const char *secret,
36 size_t size, size_t chunk_size)
39 char *md5_string = NULL;
40 unsigned char md5_hash[MD5_DIGEST_LENGTH] = { 0 };
47 data = file_data_read(path, size, chunk_size, 0);
52 MD5_Update(&ctx, data, size);
53 MD5_Update(&ctx, secret, strlen(secret));
54 MD5_Final((unsigned char *) &md5_hash, &ctx);
56 md5_string = data2string(&md5_hash, sizeof(md5_hash));
61 int ipc_nv_data_path_check(struct ipc_client *client)
71 path = ipc_client_nv_data_path(client);
72 size = ipc_client_nv_data_size(client);
73 if (path == NULL || size == 0)
78 ipc_client_log(client, "Checking nv_data path failed");
82 if (st.st_size != size) {
83 ipc_client_log(client, "Checking nv_data size failed");
87 ipc_client_log(client, "Checked nv_data path");
92 int ipc_nv_data_md5_path_check(struct ipc_client *client)
101 md5_path = ipc_client_nv_data_md5_path(client);
102 if (md5_path == NULL)
105 rc = stat(md5_path, &st);
107 ipc_client_log(client, "Checking nv_data md5 path failed");
111 if (st.st_size < 2 * sizeof(char) * MD5_DIGEST_LENGTH) {
112 ipc_client_log(client, "Checking nv_data md5 size failed");
116 ipc_client_log(client, "Checked nv_data md5 path");
121 int ipc_nv_data_backup_path_check(struct ipc_client *client)
131 backup_path = ipc_client_nv_data_backup_path(client);
132 size = ipc_client_nv_data_size(client);
133 if (backup_path == NULL || size == 0)
136 rc = stat(backup_path, &st);
138 ipc_client_log(client, "Checking nv_data backup path failed");
142 if (st.st_size != size) {
143 ipc_client_log(client, "Checking nv_data backup size failed");
147 ipc_client_log(client, "Checked nv_data backup path");
152 int ipc_nv_data_backup_md5_path_check(struct ipc_client *client)
155 char *backup_md5_path;
161 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
162 if (backup_md5_path == NULL)
165 rc = stat(backup_md5_path, &st);
167 ipc_client_log(client, "Checking nv_data backup md5 path failed");
171 if (st.st_size < 2 * sizeof(char) * MD5_DIGEST_LENGTH) {
172 ipc_client_log(client, "Checking nv_data backup md5 size failed");
176 ipc_client_log(client, "Checked nv_data backup md5 path");
181 int ipc_nv_data_check(struct ipc_client *client)
188 char *md5_string = NULL;
197 path = ipc_client_nv_data_path(client);
198 md5_path = ipc_client_nv_data_md5_path(client);
199 secret = ipc_client_nv_data_secret(client);
200 size = ipc_client_nv_data_size(client);
201 chunk_size = ipc_client_nv_data_chunk_size(client);
202 if (path == NULL || md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
205 rc = ipc_nv_data_path_check(client);
207 ipc_client_log(client, "Checking nv_data path failed");
211 rc = ipc_nv_data_md5_path_check(client);
213 ipc_client_log(client, "Checking nv_data md5 path failed");
217 md5_string = ipc_nv_data_md5_calculate(path, secret, size, chunk_size);
218 if (md5_string == NULL) {
219 ipc_client_log(client, "Calculating nv_data md5 failed");
222 ipc_client_log(client, "Calculated nv_data md5: %s", md5_string);
224 length = strlen(md5_string);
226 buffer = file_data_read(md5_path, length, length, 0);
227 if (buffer == NULL) {
228 ipc_client_log(client, "Reading nv_data md5 failed");
232 string = strndup(buffer, length);
233 ipc_client_log(client, "Read nv_data md5: %s", string);
235 rc = strncmp(md5_string, string, length);
237 ipc_client_log(client, "Matching nv_data md5 failed");
254 if (md5_string != NULL)
260 int ipc_nv_data_backup_check(struct ipc_client *client)
263 char *backup_md5_path;
267 char *backup_md5_string = NULL;
276 backup_path = ipc_client_nv_data_backup_path(client);
277 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
278 secret = ipc_client_nv_data_secret(client);
279 size = ipc_client_nv_data_size(client);
280 chunk_size = ipc_client_nv_data_chunk_size(client);
281 if (backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
284 rc = ipc_nv_data_backup_path_check(client);
286 ipc_client_log(client, "Checking nv_data backup path failed");
290 rc = ipc_nv_data_backup_md5_path_check(client);
292 ipc_client_log(client, "Checking nv_data backup md5 path failed");
296 backup_md5_string = ipc_nv_data_md5_calculate(backup_path, secret, size, chunk_size);
297 if (backup_md5_string == NULL) {
298 ipc_client_log(client, "Calculating nv_data backup md5 failed");
301 ipc_client_log(client, "Calculated nv_data backup md5: %s", backup_md5_string);
303 length = strlen(backup_md5_string);
305 buffer = file_data_read(backup_md5_path, length, length, 0);
306 if (buffer == NULL) {
307 ipc_client_log(client, "Reading nv_data backup md5 failed");
311 string = strndup(buffer, length);
312 ipc_client_log(client, "Read nv_data backup md5: %s", string);
314 rc = strncmp(backup_md5_string, string, length);
316 ipc_client_log(client, "Matching nv_data backup md5 failed");
333 if (backup_md5_string != NULL)
334 free(backup_md5_string);
339 int ipc_nv_data_backup(struct ipc_client *client)
344 char *backup_md5_path;
348 char *md5_string = NULL;
355 path = ipc_client_nv_data_path(client);
356 backup_path = ipc_client_nv_data_backup_path(client);
357 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
358 secret = ipc_client_nv_data_secret(client);
359 size = ipc_client_nv_data_size(client);
360 chunk_size = ipc_client_nv_data_chunk_size(client);
361 if (path == NULL || backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
364 rc = ipc_nv_data_path_check(client);
366 ipc_client_log(client, "Checking nv_data path failed");
370 data = file_data_read(path, size, chunk_size, 0);
372 ipc_client_log(client, "Reading nv_data failed");
376 md5_string = ipc_nv_data_md5_calculate(path, secret, size, chunk_size);
377 if (md5_string == NULL) {
378 ipc_client_log(client, "Calculating nv_data md5 failed");
382 length = strlen(md5_string);
384 rc = unlink(backup_path);
386 ipc_client_log(client, "Removing nv_data backup path failed");
388 rc = file_data_write(backup_path, data, size, chunk_size, 0);
390 ipc_client_log(client, "Writing nv_data backup failed");
394 rc = unlink(backup_md5_path);
396 ipc_client_log(client, "Removing nv_data backup md5 path failed");
398 rc = file_data_write(backup_md5_path, md5_string, length, length, 0);
400 ipc_client_log(client, "Writing nv_data backup md5 failed");
404 ipc_client_log(client, "Backed up nv_data");
413 if (md5_string != NULL)
422 int ipc_nv_data_restore(struct ipc_client *client)
428 char *backup_md5_path;
438 path = ipc_client_nv_data_path(client);
439 md5_path = ipc_client_nv_data_md5_path(client);
440 backup_path = ipc_client_nv_data_backup_path(client);
441 backup_md5_path = ipc_client_nv_data_backup_md5_path(client);
442 secret = ipc_client_nv_data_secret(client);
443 size = ipc_client_nv_data_size(client);
444 chunk_size = ipc_client_nv_data_chunk_size(client);
445 if (path == NULL || md5_path == NULL || backup_path == NULL || backup_md5_path == NULL || secret == NULL || size == 0 || chunk_size == 0)
448 rc = ipc_nv_data_backup_check(client);
450 ipc_client_log(client, "Checking nv_data backup failed");
454 data = file_data_read(backup_path, size, chunk_size, 0);
456 ipc_client_log(client, "Reading nv_data backup failed");
462 ipc_client_log(client, "Removing nv_data path failed");
464 rc = file_data_write(path, data, size, chunk_size, 0);
466 ipc_client_log(client, "Writing nv_data failed");
473 length = 2 * sizeof(char) * MD5_DIGEST_LENGTH;
475 data = file_data_read(backup_md5_path, length, length, 0);
477 ipc_client_log(client, "Reading nv_data backup md5 failed");
481 rc = unlink(md5_path);
483 ipc_client_log(client, "Removing nv_data md5 path failed");
485 rc = file_data_write(md5_path, data, length, length, 0);
487 ipc_client_log(client, "Writing nv_data md5 failed");
491 ipc_client_log(client, "Restored nv_data");
506 void *ipc_nv_data_load(struct ipc_client *client)
517 path = ipc_client_nv_data_path(client);
518 size = ipc_client_nv_data_size(client);
519 chunk_size = ipc_client_nv_data_chunk_size(client);
520 if (path == NULL || size == 0 || chunk_size == 0)
523 rc = ipc_nv_data_check(client);
525 ipc_client_log(client, "Checking nv_data failed");
527 rc = ipc_nv_data_restore(client);
529 ipc_client_log(client, "Restoring nv_data failed");
533 rc = ipc_nv_data_check(client);
535 ipc_client_log(client, "Checking nv_data failed");
540 rc = ipc_nv_data_backup_path_check(client);
542 ipc_client_log(client, "Checking nv_data backup path failed");
544 rc = ipc_nv_data_backup(client);
546 ipc_client_log(client, "Backing up nv_data failed");
549 data = file_data_read(path, size, chunk_size, 0);
551 ipc_client_log(client, "Reading nv_data failed");
558 void *ipc_nv_data_read(struct ipc_client *client, size_t size,
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 > size ? 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 > size ? 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 = 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